diff options
author | yuemingw <yuemingw@google.com> | 2018-10-24 13:02:05 +0100 |
---|---|---|
committer | yuemingw <yuemingw@google.com> | 2018-12-10 19:39:29 +0000 |
commit | a35990b63396851c273aebac09e21329a2324def (patch) | |
tree | b7c4efb7dcd1926272950ddeba9abcfa3c4d7cfd | |
parent | 09b130529cf11cf6d556e801a37812f276260269 (diff) | |
download | packages_apps_Settings-a35990b63396851c273aebac09e21329a2324def.tar.gz packages_apps_Settings-a35990b63396851c273aebac09e21329a2324def.tar.bz2 packages_apps_Settings-a35990b63396851c273aebac09e21329a2324def.zip |
Add Cross profile calendar Settings UI.
Bug: 117976974
Test: make ROBOTEST_FILTER=CrossProfileCalendarPreferenceControllerTest -j40 RunSettingsRoboTests
Change-Id: Ieb4dcfb8091e2c63f4372af220695297c7bb116d
6 files changed, 273 insertions, 1 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml index 0b79470e2b..cbb5e3be3a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9458,6 +9458,11 @@ <string name="managed_profile_contact_search_title">Contact search</string> <!-- [CHAR LIMIT=NONE] The preference summary for enabling cross-profile remote contact search --> <string name="managed_profile_contact_search_summary">Allow contact searches by your organization to identify callers and contacts</string> + <!-- [CHAR LIMIT=60] The preference title for enabling cross profile calendar sync --> + <string name="cross_profile_calendar_title">Cross-profile calendar</string> + <!-- [CHAR LIMIT=NONE] The preference summary for enabling cross profile calendar sync --> + <string name="cross_profile_calendar_summary">Show work events on personal calendar</string> + <!-- Time in hours --> <plurals name="hours"> diff --git a/res/xml/managed_profile_settings.xml b/res/xml/managed_profile_settings.xml index ee1e4fadec..bd44cc1a30 100644 --- a/res/xml/managed_profile_settings.xml +++ b/res/xml/managed_profile_settings.xml @@ -32,4 +32,11 @@ settings:useAdditionalSummary="true" settings:controller="com.android.settings.accounts.ContactSearchPreferenceController"/> + <com.android.settingslib.RestrictedSwitchPreference + android:key="cross_profile_calendar" + android:summary="@string/cross_profile_calendar_summary" + android:title="@string/cross_profile_calendar_title" + settings:useAdditionalSummary="true" + settings:controller="com.android.settings.accounts.CrossProfileCalendarPreferenceController"/> + </PreferenceScreen>
\ No newline at end of file diff --git a/src/com/android/settings/accounts/CrossProfileCalendarPreferenceController.java b/src/com/android/settings/accounts/CrossProfileCalendarPreferenceController.java new file mode 100644 index 0000000000..38c95dcc7a --- /dev/null +++ b/src/com/android/settings/accounts/CrossProfileCalendarPreferenceController.java @@ -0,0 +1,79 @@ +/* + * 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 android.provider.Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED; + +import android.content.Context; +import android.os.UserHandle; +import android.provider.Settings; + +import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.TogglePreferenceController; +import com.android.settings.slices.SliceData; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedLockUtilsInternal; +import com.android.settingslib.RestrictedSwitchPreference; + +import androidx.preference.Preference; + +public class CrossProfileCalendarPreferenceController extends TogglePreferenceController { + + private UserHandle mManagedUser; + + public CrossProfileCalendarPreferenceController(Context context, String key) { + super(context, key); + } + + public void setManagedUser(UserHandle managedUser) { + mManagedUser = managedUser; + } + + @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); + } + } + + @Override + public boolean isChecked() { + if (mManagedUser == null) { + return false; + } + return Settings.Secure.getIntForUser(mContext.getContentResolver(), + CROSS_PROFILE_CALENDAR_ENABLED, /* default= */ 0, + mManagedUser.getIdentifier()) == 1; + } + + @Override + public boolean setChecked(boolean isChecked) { + if (mManagedUser == null) { + return false; + } + final int value = isChecked ? 1 : 0; + return Settings.Secure.putIntForUser(mContext.getContentResolver(), + CROSS_PROFILE_CALENDAR_ENABLED, value, mManagedUser.getIdentifier()); + } +}
\ 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 07e5845898..dccd7f6749 100644 --- a/src/com/android/settings/accounts/ManagedProfileSettings.java +++ b/src/com/android/settings/accounts/ManagedProfileSettings.java @@ -23,17 +23,25 @@ import android.content.IntentFilter; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; +import android.provider.SearchIndexableResource; import android.util.Log; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; +import com.android.settingslib.search.SearchIndexable; + +import java.util.ArrayList; +import java.util.List; /** * Setting page for managed profile. * FIXME: It currently assumes there is only one managed profile. */ +@SearchIndexable public class ManagedProfileSettings extends DashboardFragment { private UserManager mUserManager; @@ -63,6 +71,7 @@ public class ManagedProfileSettings extends DashboardFragment { } use(WorkModePreferenceController.class).setManagedUser(mManagedUser); use(ContactSearchPreferenceController.class).setManagedUser(mManagedUser); + use(CrossProfileCalendarPreferenceController.class).setManagedUser(mManagedUser); } @Override @@ -99,6 +108,23 @@ public class ManagedProfileSettings extends DashboardFragment { return MetricsProto.MetricsEvent.ACCOUNTS_WORK_PROFILE_SETTINGS; } + public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, + boolean enabled) { + final ArrayList<SearchIndexableResource> result = new ArrayList<>(); + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.managed_profile_settings; + result.add(sir); + return result; + } + @Override + protected boolean isPageSearchEnabled(Context context) { + return false; + } + }; + private class ManagedProfileBroadcastReceiver extends BroadcastReceiver { @Override diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider index e105dfc898..ab06f751c7 100644 --- a/tests/robotests/assets/grandfather_not_implementing_index_provider +++ b/tests/robotests/assets/grandfather_not_implementing_index_provider @@ -7,7 +7,6 @@ com.android.settings.accessibility.ToggleScreenReaderPreferenceFragmentForSetupW com.android.settings.accessibility.ToggleSelectToSpeakPreferenceFragmentForSetupWizard com.android.settings.accounts.AccountDetailDashboardFragment com.android.settings.accounts.AccountSyncSettings -com.android.settings.accounts.ManagedProfileSettings com.android.settings.applications.appinfo.AppInfoDashboardFragment com.android.settings.applications.appinfo.DrawOverlayDetails com.android.settings.applications.appinfo.ExternalSourcesDetails diff --git a/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarPreferenceControllerTest.java new file mode 100644 index 0000000000..4469282a36 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accounts/CrossProfileCalendarPreferenceControllerTest.java @@ -0,0 +1,156 @@ +/* + * 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 android.provider.Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED; + +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 android.provider.Settings; +import android.util.ArraySet; +import android.util.Log; + +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.RestrictedSwitchPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowDevicePolicyManager; + +import java.util.Collections; +import java.util.Set; + +@RunWith(SettingsRobolectricTestRunner.class) +public class CrossProfileCalendarPreferenceControllerTest { + + private static final String PREF_KEY = "cross_profile_calendar"; + 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 RestrictedSwitchPreference mPreference; + private Context mContext; + private CrossProfileCalendarPreferenceController mController; + private ShadowDevicePolicyManager dpm; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + mController = new CrossProfileCalendarPreferenceController(mContext, PREF_KEY); + mController.setManagedUser(mManagedUser); + mPreference = spy(new RestrictedSwitchPreference(mContext)); + dpm = 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_noManagedUser_DISABLED() { + mController.setManagedUser(null); + + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(CrossProfileCalendarPreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_hasManagedUser_AVAILABLE() { + mController.setManagedUser(mManagedUser); + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(CrossProfileCalendarPreferenceController.AVAILABLE); + } + + @Test + public void updateStateToDisabled_isNotChecked() { + Settings.Secure.putIntForUser(mContext.getContentResolver(), + CROSS_PROFILE_CALENDAR_ENABLED, 0, mManagedUser.getIdentifier()); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void updateStateToEnabled_isChecked() throws Exception { + // Put 0 first so we know the value is not originally 1. + Settings.Secure.putIntForUser(mContext.getContentResolver(), + CROSS_PROFILE_CALENDAR_ENABLED, 0, mManagedUser.getIdentifier()); + mController.updateState(mPreference); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + CROSS_PROFILE_CALENDAR_ENABLED, 1, mManagedUser.getIdentifier()); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void updateState_noPackageAllowed_preferenceShouldBeDisabled() throws Exception { + dpm.setProfileOwner(TEST_COMPONENT_NAME); + + mController.updateState(mPreference); + verify(mPreference).setDisabledByAdmin(any()); + } + + @Test + public void updateState_somePackagesAllowed_preferenceShouldNotBeDisabled() throws Exception { + dpm.setProfileOwner(TEST_COMPONENT_NAME); + dpm.addCrossProfileCalendarPackage(TEST_COMPONENT_NAME, TEST_PACKAGE_NAME); + + mController.updateState(mPreference); + verify(mPreference).setDisabledByAdmin(null); + } + + @Test + public void onPreferenceChangeToFalse_shouldUpdateProviderValue() { + mController.onPreferenceChange(mPreference, false); + assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(), + CROSS_PROFILE_CALENDAR_ENABLED, 1, mManagedUser.getIdentifier())) + .isEqualTo(0); + } + + @Test + public void onPreferenceChangeToTrue_shouldUpdateProviderValue() { + // Change to false first so we know the value is not originally 1. + mController.onPreferenceChange(mPreference, false); + + mController.onPreferenceChange(mPreference, true); + assertThat(Settings.Secure.getIntForUser(mContext.getContentResolver(), + CROSS_PROFILE_CALENDAR_ENABLED, 0, mManagedUser.getIdentifier())) + .isEqualTo(1); + } +}
\ No newline at end of file |