From ed701572d76c6f358c33460b8eb170916149a2cf Mon Sep 17 00:00:00 2001 From: Jonathan Scott Date: Mon, 15 Apr 2019 15:36:17 +0100 Subject: [PATCH] Don't show policy transparency UI for cross-profile setting. Also removes the switch if cross-profile calendar is disabled by admin. Test: atest ManagedProfileSettingsTest Fixes: 123930863 Change-Id: Ieeb9266e8833d7ca730fedb5e947b03ec7d18d3c --- res/xml/managed_profile_settings.xml | 11 ++- ...eCalendarDisabledPreferenceController.java | 47 +++++++++ ...ssProfileCalendarPreferenceController.java | 51 ++++++---- .../accounts/ManagedProfileSettings.java | 8 ++ ...endarDisabledPreferenceControllerTest.java | 99 +++++++++++++++++++ ...ofileCalendarPreferenceControllerTest.java | 18 ++-- 6 files changed, 206 insertions(+), 28 deletions(-) create mode 100644 src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceControllerTest.java diff --git a/res/xml/managed_profile_settings.xml b/res/xml/managed_profile_settings.xml index bd44cc1a307..7b65a3d30b0 100644 --- a/res/xml/managed_profile_settings.xml +++ b/res/xml/managed_profile_settings.xml @@ -32,11 +32,18 @@ settings:useAdditionalSummary="true" settings:controller="com.android.settings.accounts.ContactSearchPreferenceController"/> - + + \ No newline at end of file diff --git a/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceController.java b/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceController.java new file mode 100644 index 00000000000..c0879823792 --- /dev/null +++ b/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceController.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 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.settings.accounts; +import static com.android.settings.accounts.CrossProfileCalendarPreferenceController.isCrossProfileCalendarDisallowedByAdmin; + +import android.content.Context; +import android.os.UserHandle; + +import com.android.settings.core.BasePreferenceController; + +public class CrossProfileCalendarDisabledPreferenceController extends BasePreferenceController { + private UserHandle mManagedUser; + + public void setManagedUser(UserHandle managedUser) { + mManagedUser = managedUser; + } + + public CrossProfileCalendarDisabledPreferenceController(Context context, + String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + if (mManagedUser != null + && isCrossProfileCalendarDisallowedByAdmin( + mContext, mManagedUser.getIdentifier())) { + return AVAILABLE; + } + + return DISABLED_FOR_USER; + } +} diff --git a/src/com/android/settings/accounts/CrossProfileCalendarPreferenceController.java b/src/com/android/settings/accounts/CrossProfileCalendarPreferenceController.java index aa314d6974a..863e790719f 100644 --- a/src/com/android/settings/accounts/CrossProfileCalendarPreferenceController.java +++ b/src/com/android/settings/accounts/CrossProfileCalendarPreferenceController.java @@ -15,19 +15,21 @@ package com.android.settings.accounts; import static android.provider.Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED; +import android.app.admin.DevicePolicyManager; import android.content.Context; +import android.content.pm.PackageManager; import android.os.UserHandle; import android.provider.Settings; - -import androidx.preference.Preference; +import android.util.Log; import com.android.settings.core.TogglePreferenceController; -import com.android.settingslib.RestrictedLockUtils; -import com.android.settingslib.RestrictedLockUtilsInternal; -import com.android.settingslib.RestrictedSwitchPreference; + +import java.util.Set; public class CrossProfileCalendarPreferenceController extends TogglePreferenceController { + private static final String TAG = "CrossProfileCalendarPreferenceController"; + private UserHandle mManagedUser; public CrossProfileCalendarPreferenceController(Context context, String key) { @@ -40,19 +42,13 @@ public class CrossProfileCalendarPreferenceController extends TogglePreferenceCo @Override public int getAvailabilityStatus() { - return (mManagedUser != null) ? AVAILABLE : DISABLED_FOR_USER; - } - - @Override - public void updateState(Preference preference) { - super.updateState(preference); - if (preference instanceof RestrictedSwitchPreference && mManagedUser != null) { - final RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference; - final RestrictedLockUtils.EnforcedAdmin enforcedAdmin = - RestrictedLockUtilsInternal.getCrossProfileCalendarEnforcingAdmin( - mContext, mManagedUser.getIdentifier()); - pref.setDisabledByAdmin(enforcedAdmin); + if (mManagedUser != null + && !isCrossProfileCalendarDisallowedByAdmin( + mContext, mManagedUser.getIdentifier())) { + return AVAILABLE; } + + return DISABLED_FOR_USER; } @Override @@ -74,4 +70,25 @@ public class CrossProfileCalendarPreferenceController extends TogglePreferenceCo return Settings.Secure.putIntForUser(mContext.getContentResolver(), CROSS_PROFILE_CALENDAR_ENABLED, value, mManagedUser.getIdentifier()); } + + static boolean isCrossProfileCalendarDisallowedByAdmin(Context context, int userId) { + final Context managedProfileContext = createPackageContextAsUser(context, userId); + final DevicePolicyManager dpm = managedProfileContext.getSystemService( + DevicePolicyManager.class); + if (dpm == null) { + return true; + } + final Set packages = dpm.getCrossProfileCalendarPackages(); + return packages != null && packages.isEmpty(); + } + + private static Context createPackageContextAsUser(Context context, int userId) { + try { + return context.createPackageContextAsUser( + context.getPackageName(), 0 /* flags */, UserHandle.of(userId)); + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "Failed to create user context", e); + } + return null; + } } \ No newline at end of file diff --git a/src/com/android/settings/accounts/ManagedProfileSettings.java b/src/com/android/settings/accounts/ManagedProfileSettings.java index a4105efa779..1f18d07ec7e 100644 --- a/src/com/android/settings/accounts/ManagedProfileSettings.java +++ b/src/com/android/settings/accounts/ManagedProfileSettings.java @@ -16,17 +16,23 @@ package com.android.settings.accounts; +import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; import android.provider.SearchIndexableResource; import android.util.Log; +import androidx.preference.Preference; +import androidx.preference.PreferenceGroup; +import androidx.preference.PreferenceManager; + import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.dashboard.DashboardFragment; @@ -36,6 +42,7 @@ import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; import java.util.List; +import java.util.Set; /** * Setting page for managed profile. @@ -72,6 +79,7 @@ public class ManagedProfileSettings extends DashboardFragment { use(WorkModePreferenceController.class).setManagedUser(mManagedUser); use(ContactSearchPreferenceController.class).setManagedUser(mManagedUser); use(CrossProfileCalendarPreferenceController.class).setManagedUser(mManagedUser); + use(CrossProfileCalendarDisabledPreferenceController.class).setManagedUser(mManagedUser); } @Override diff --git a/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceControllerTest.java new file mode 100644 index 00000000000..2226e2c4e1d --- /dev/null +++ b/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarDisabledPreferenceControllerTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 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.settings.accounts; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.robolectric.RuntimeEnvironment.application; + +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.Context; +import android.os.UserHandle; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; +import org.robolectric.shadows.ShadowDevicePolicyManager; + +import java.util.Collections; + +@RunWith(RobolectricTestRunner.class) +public class CrossProfileCalendarDisabledPreferenceControllerTest { + + private static final String PREF_KEY = "cross_profile_calendar_disabled"; + private static final int MANAGED_USER_ID = 10; + private static final String TEST_PACKAGE_NAME = "com.test"; + private static final ComponentName TEST_COMPONENT_NAME = new ComponentName("test", "test"); + + @Mock + private UserHandle mManagedUser; + + private Context mContext; + private CrossProfileCalendarDisabledPreferenceController mController; + private ShadowDevicePolicyManager mDpm; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + mController = new CrossProfileCalendarDisabledPreferenceController(mContext, PREF_KEY); + mController.setManagedUser(mManagedUser); + mDpm = Shadows.shadowOf(application.getSystemService(DevicePolicyManager.class)); + + when(mManagedUser.getIdentifier()).thenReturn(MANAGED_USER_ID); + doReturn(mContext).when(mContext).createPackageContextAsUser( + any(String.class), anyInt(), any(UserHandle.class)); + } + + @Test + public void getAvailabilityStatus_noPackageAllowed_shouldBeAvailable() { + mDpm.setProfileOwner(TEST_COMPONENT_NAME); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void getAvailabilityStatus_somePackagesAllowed_shouldBeDisabledForUser() { + mDpm.setProfileOwner(TEST_COMPONENT_NAME); + mDpm.setCrossProfileCalendarPackages(TEST_COMPONENT_NAME, + Collections.singleton(TEST_PACKAGE_NAME)); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER); + } + + @Test + public void getAvailabilityStatus_allPackagesAllowed_shouldBeDisabledForUser() { + mDpm.setProfileOwner(TEST_COMPONENT_NAME); + mDpm.setCrossProfileCalendarPackages(TEST_COMPONENT_NAME, null); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarPreferenceControllerTest.java index c6a48a889a9..2cbed9782e6 100644 --- a/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarPreferenceControllerTest.java @@ -17,6 +17,9 @@ package com.android.settings.accounts; import static android.provider.Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED; +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -117,30 +120,27 @@ public class CrossProfileCalendarPreferenceControllerTest { } @Test - public void updateState_noPackageAllowed_preferenceShouldBeDisabled() throws Exception { + public void getAvailabilityStatus_noPackageAllowed_shouldBeDisabledForUser() throws Exception { dpm.setProfileOwner(TEST_COMPONENT_NAME); - mController.updateState(mPreference); - verify(mPreference).setDisabledByAdmin(any()); + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_FOR_USER); } @Test - public void updateState_somePackagesAllowed_preferenceShouldNotBeDisabled() throws Exception { + public void getAvailabilityStatus_somePackagesAllowed_shouldBeAvailable() throws Exception { dpm.setProfileOwner(TEST_COMPONENT_NAME); dpm.setCrossProfileCalendarPackages(TEST_COMPONENT_NAME, Collections.singleton(TEST_PACKAGE_NAME)); - mController.updateState(mPreference); - verify(mPreference).setDisabledByAdmin(null); + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); } @Test - public void updateState_allPackagesAllowed_preferenceShouldNotBeDisabled() throws Exception { + public void getAvailabilityStatus_allPackagesAllowed_shouldBeAvailable() throws Exception { dpm.setProfileOwner(TEST_COMPONENT_NAME); dpm.setCrossProfileCalendarPackages(TEST_COMPONENT_NAME, null); - mController.updateState(mPreference); - verify(mPreference).setDisabledByAdmin(null); + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); } @Test