From 13f569ebd676cf1616b039d0d8aa141fff34be49 Mon Sep 17 00:00:00 2001 From: Bartosz Fabianowski Date: Fri, 13 Jan 2017 17:41:38 +0100 Subject: [PATCH] Add number of enterprise-installed apps to Privacy Settings page This CL adds information about the number of apps that were installed by the admin to the Enterprise Privacy Settings page. Test: make RunSettingsRoboTests Bug: 32692748 Change-Id: Ib710a1249db6d285da962122fd3dfb35a43752a1 --- res/values/strings.xml | 5 + res/xml/enterprise_privacy_settings.xml | 4 + .../ApplicationFeatureProvider.java | 12 +- .../ApplicationFeatureProviderImpl.java | 9 +- .../applications/InstalledAppCounter.java | 15 ++- .../applications/ManageApplications.java | 2 +- .../applications/PackageManagerWrapper.java | 9 ++ .../PackageManagerWrapperImpl.java | 6 + ...InstalledPackagesPreferenceController.java | 63 ++++++++++ .../enterprise/EnterprisePrivacySettings.java | 1 + ...InstalledPackagesPreferenceController.java | 10 +- .../ApplicationFeatureProviderImplTest.java | 32 +++-- .../applications/InstalledAppCounterTest.java | 62 ++++++++-- ...alledPackagesPreferenceControllerTest.java | 113 ++++++++++++++++++ .../EnterprisePrivacySettingsTest.java | 5 +- ...alledPackagesPreferenceControllerTest.java | 6 +- 16 files changed, 314 insertions(+), 40 deletions(-) create mode 100644 src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index dc6be695948..cae4351093c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8011,6 +8011,11 @@ Always-on VPN turned on in your work profile Global HTTP proxy set + + + %d app installed by your admin + %d apps installed by your admin + Photos & Videos diff --git a/res/xml/enterprise_privacy_settings.xml b/res/xml/enterprise_privacy_settings.xml index 0358911a10f..9fed938c138 100644 --- a/res/xml/enterprise_privacy_settings.xml +++ b/res/xml/enterprise_privacy_settings.xml @@ -73,6 +73,10 @@ android:title="@string/enterprise_privacy_global_http_proxy" settings:allowDividerBelow="true" settings:multiLine="true"/> + diff --git a/src/com/android/settings/applications/ApplicationFeatureProvider.java b/src/com/android/settings/applications/ApplicationFeatureProvider.java index bb0fd4c6b53..1db33a6ef01 100644 --- a/src/com/android/settings/applications/ApplicationFeatureProvider.java +++ b/src/com/android/settings/applications/ApplicationFeatureProvider.java @@ -26,11 +26,21 @@ public interface ApplicationFeatureProvider { */ AppHeaderController newAppHeaderController(Fragment fragment, View appHeader); + /** + * Count all installed packages, irrespective of install reason. + */ + public static final int IGNORE_INSTALL_REASON = -1; + /** * Asynchronously calculates the total number of apps installed on the device, across all users * and managed profiles. + * + * @param installReason Only consider packages with this install reason; may be any install + * reason defined in {@link android.content.pm.PackageManager} or + * {@link #IGNORE_INSTALL_REASON} to count all packages, irrespective of install reason. + * @param callback The callback to invoke with the result */ - void calculateNumberOfInstalledApps(NumberOfInstalledAppsCallback callback); + void calculateNumberOfInstalledApps(int installReason, NumberOfInstalledAppsCallback callback); /** * Callback that receives the total number of packages installed on the device. diff --git a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java index a284a0a83bf..902008cd00a 100644 --- a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java +++ b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java @@ -42,15 +42,16 @@ public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvide } @Override - public void calculateNumberOfInstalledApps(NumberOfInstalledAppsCallback callback) { - new AllUserInstalledAppCounter(callback).execute(); + public void calculateNumberOfInstalledApps(int installReason, + NumberOfInstalledAppsCallback callback) { + new AllUserInstalledAppCounter(installReason, callback).execute(); } private class AllUserInstalledAppCounter extends InstalledAppCounter { private NumberOfInstalledAppsCallback mCallback; - AllUserInstalledAppCounter(NumberOfInstalledAppsCallback callback) { - super(mContext, ApplicationFeatureProviderImpl.this.mPm); + AllUserInstalledAppCounter(int installReason, NumberOfInstalledAppsCallback callback) { + super(mContext, installReason, ApplicationFeatureProviderImpl.this.mPm); mCallback = callback; } diff --git a/src/com/android/settings/applications/InstalledAppCounter.java b/src/com/android/settings/applications/InstalledAppCounter.java index 9faef7a22f9..251b0a2aea3 100644 --- a/src/com/android/settings/applications/InstalledAppCounter.java +++ b/src/com/android/settings/applications/InstalledAppCounter.java @@ -25,12 +25,24 @@ import java.util.List; public abstract class InstalledAppCounter extends AppCounter { - public InstalledAppCounter(Context context, PackageManagerWrapper packageManager) { + private final int mInstallReason; + private final PackageManagerWrapper mPackageManager; + + public InstalledAppCounter(Context context, int installReason, + PackageManagerWrapper packageManager) { super(context, packageManager); + mInstallReason = installReason; + mPackageManager = packageManager; } @Override protected boolean includeInCount(ApplicationInfo info) { + final int userId = UserHandle.getUserId(info.uid); + if (mInstallReason != ApplicationFeatureProvider.IGNORE_INSTALL_REASON + && mPackageManager.getInstallReason(info.packageName, + new UserHandle(userId)) != mInstallReason) { + return false; + } if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { return true; } @@ -40,7 +52,6 @@ public abstract class InstalledAppCounter extends AppCounter { Intent launchIntent = new Intent(Intent.ACTION_MAIN, null) .addCategory(Intent.CATEGORY_LAUNCHER) .setPackage(info.packageName); - int userId = UserHandle.getUserId(info.uid); List intents = mPm.queryIntentActivitiesAsUser( launchIntent, PackageManager.GET_DISABLED_COMPONENTS diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java index 2b4427e7e27..43bb02a4fdd 100644 --- a/src/com/android/settings/applications/ManageApplications.java +++ b/src/com/android/settings/applications/ManageApplications.java @@ -1252,7 +1252,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment @Override public void setListening(boolean listening) { if (listening) { - new InstalledAppCounter(mContext, + new InstalledAppCounter(mContext, ApplicationFeatureProvider.IGNORE_INSTALL_REASON, new PackageManagerWrapperImpl(mContext.getPackageManager())) { @Override protected void onCountComplete(int num) { diff --git a/src/com/android/settings/applications/PackageManagerWrapper.java b/src/com/android/settings/applications/PackageManagerWrapper.java index 6c783d80736..4166ccf9c50 100644 --- a/src/com/android/settings/applications/PackageManagerWrapper.java +++ b/src/com/android/settings/applications/PackageManagerWrapper.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.UserHandle; import java.util.List; @@ -56,4 +57,12 @@ public interface PackageManagerWrapper { * @see android.content.pm.PackageManager#queryIntentActivitiesAsUser */ List queryIntentActivitiesAsUser(Intent intent, int flags, int userId); + + + /** + * Calls {@code PackageManager.getInstallReason()}. + * + * @see android.content.pm.PackageManager#getInstallReason + */ + int getInstallReason(String packageName, UserHandle user); } diff --git a/src/com/android/settings/applications/PackageManagerWrapperImpl.java b/src/com/android/settings/applications/PackageManagerWrapperImpl.java index db1d30a7d60..2427cceda3d 100644 --- a/src/com/android/settings/applications/PackageManagerWrapperImpl.java +++ b/src/com/android/settings/applications/PackageManagerWrapperImpl.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.UserHandle; import java.util.List; @@ -50,4 +51,9 @@ public class PackageManagerWrapperImpl implements PackageManagerWrapper { public List queryIntentActivitiesAsUser(Intent intent, int flags, int userId) { return mPm.queryIntentActivitiesAsUser(intent, flags, userId); } + + @Override + public int getInstallReason(String packageName, UserHandle user) { + return mPm.getInstallReason(packageName, user); + } } diff --git a/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java b/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java new file mode 100644 index 00000000000..1fbb04a12ca --- /dev/null +++ b/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceController.java @@ -0,0 +1,63 @@ +/* + * 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 com.android.settings.enterprise; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.support.v7.preference.Preference; + +import com.android.settings.R; +import com.android.settings.applications.ApplicationFeatureProvider; +import com.android.settings.core.PreferenceController; +import com.android.settings.overlay.FeatureFactory; + +public class EnterpriseInstalledPackagesPreferenceController extends PreferenceController { + + private static final String KEY_NUMBER_ENTERPRISE_INSTALLED_PACKAGES + = "number_enterprise_installed_packages"; + private final ApplicationFeatureProvider mFeatureProvider; + + public EnterpriseInstalledPackagesPreferenceController(Context context) { + super(context); + mFeatureProvider = FeatureFactory.getFactory(context) + .getApplicationFeatureProvider(context); + } + + @Override + public void updateState(Preference preference) { + mFeatureProvider.calculateNumberOfInstalledApps( + PackageManager.INSTALL_REASON_POLICY, + (num) -> { + if (num == 0) { + preference.setVisible(false); + } else { + preference.setVisible(true); + preference.setTitle(mContext.getResources().getQuantityString( + R.plurals.enterprise_privacy_number_enterprise_installed_packages, + num, num)); + } + }); + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public String getPreferenceKey() { + return KEY_NUMBER_ENTERPRISE_INSTALLED_PACKAGES; + } +} diff --git a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java index 8f1f22beec0..2cd28629a6f 100644 --- a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java +++ b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java @@ -64,6 +64,7 @@ public class EnterprisePrivacySettings extends DashboardFragment { controllers.add(new AlwaysOnVpnPrimaryUserPreferenceController(context)); controllers.add(new AlwaysOnVpnManagedProfilePreferenceController(context)); controllers.add(new GlobalHttpProxyPreferenceController(context)); + controllers.add(new EnterpriseInstalledPackagesPreferenceController(context)); return controllers; } diff --git a/src/com/android/settings/enterprise/InstalledPackagesPreferenceController.java b/src/com/android/settings/enterprise/InstalledPackagesPreferenceController.java index a7afac0227a..91ac4c20330 100644 --- a/src/com/android/settings/enterprise/InstalledPackagesPreferenceController.java +++ b/src/com/android/settings/enterprise/InstalledPackagesPreferenceController.java @@ -36,12 +36,10 @@ public class InstalledPackagesPreferenceController extends PreferenceController @Override public void updateState(Preference preference) { mFeatureProvider.calculateNumberOfInstalledApps( - new ApplicationFeatureProvider.NumberOfInstalledAppsCallback() { - @Override - public void onNumberOfInstalledAppsResult(int num) { - preference.setTitle(mContext.getResources().getQuantityString( - R.plurals.enterprise_privacy_number_installed_packages, num, num)); - } + ApplicationFeatureProvider.IGNORE_INSTALL_REASON, + (num) -> { + preference.setTitle(mContext.getResources().getQuantityString( + R.plurals.enterprise_privacy_number_installed_packages, num, num)); }); } diff --git a/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java index 56834db89b9..615d9adbffe 100644 --- a/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java @@ -19,6 +19,7 @@ package com.android.settings.applications; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.UserInfo; +import android.os.UserHandle; import android.os.UserManager; import com.android.settings.SettingsRobolectricTestRunner; @@ -49,6 +50,9 @@ public final class ApplicationFeatureProviderImplTest { private final int MAIN_USER_ID = 0; private final int MANAGED_PROFILE_ID = 10; + private final String APP_1 = "app1"; + private final String APP_2 = "app2"; + private @Mock UserManager mUserManager; private @Mock Context mContext; private @Mock PackageManagerWrapper mPackageManager; @@ -78,22 +82,32 @@ public final class ApplicationFeatureProviderImplTest { | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS | PackageManager.MATCH_ANY_USER, MAIN_USER_ID)).thenReturn(Arrays.asList( - ApplicationTestUtils.buildInfo(MAIN_USER_ID, "app1", 0 /* flags */))); + ApplicationTestUtils.buildInfo(MAIN_USER_ID, APP_1, 0 /* flags */))); + when(mPackageManager.getInstallReason(APP_1, new UserHandle(MAIN_USER_ID))) + .thenReturn(PackageManager.INSTALL_REASON_UNKNOWN); when(mPackageManager.getInstalledApplicationsAsUser(PackageManager.GET_DISABLED_COMPONENTS | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, MANAGED_PROFILE_ID)).thenReturn(Arrays.asList( - ApplicationTestUtils.buildInfo(MANAGED_PROFILE_ID, "app2", 0 /* flags */))); + ApplicationTestUtils.buildInfo(MANAGED_PROFILE_ID, APP_2, 0 /* flags */))); + when(mPackageManager.getInstallReason(APP_2, new UserHandle(MANAGED_PROFILE_ID))) + .thenReturn(PackageManager.INSTALL_REASON_POLICY); - mProvider.calculateNumberOfInstalledApps( - new ApplicationFeatureProvider.NumberOfInstalledAppsCallback() { - @Override - public void onNumberOfInstalledAppsResult(int num) { - numberOfInstalledApps[0] = num; - } + // Count all installed apps. + mProvider.calculateNumberOfInstalledApps(ApplicationFeatureProvider.IGNORE_INSTALL_REASON, + (num) -> { + numberOfInstalledApps[0] = num; }); ShadowApplication.runBackgroundTasks(); - assertThat(numberOfInstalledApps[0]).isEqualTo(2); + + // Count apps with specific install reason only. + numberOfInstalledApps[0] = null; + mProvider.calculateNumberOfInstalledApps(PackageManager.INSTALL_REASON_POLICY, + (num) -> { + numberOfInstalledApps[0] = num; + }); + ShadowApplication.runBackgroundTasks(); + assertThat(numberOfInstalledApps[0]).isEqualTo(1); } } diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java index b6c84d095e8..3dc2e9b0481 100644 --- a/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java +++ b/tests/robotests/src/com/android/settings/applications/InstalledAppCounterTest.java @@ -22,6 +22,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; +import android.os.UserHandle; import android.os.UserManager; import com.android.settings.SettingsRobolectricTestRunner; @@ -60,6 +61,13 @@ import static org.mockito.Mockito.when; shadows = {ShadowUserManager.class}) public final class InstalledAppCounterTest { + private final String APP_1 = "app1"; + private final String APP_2 = "app2"; + private final String APP_3 = "app3"; + private final String APP_4 = "app4"; + private final String APP_5 = "app5"; + private final String APP_6 = "app6"; + private final int MAIN_USER_ID = 0; private final int MANAGED_PROFILE_ID = 10; @@ -101,14 +109,25 @@ public final class InstalledAppCounterTest { | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS | PackageManager.MATCH_ANY_USER, MAIN_USER_ID)).thenReturn(Arrays.asList( - buildInfo(MAIN_USER_ID, "app1", ApplicationInfo.FLAG_UPDATED_SYSTEM_APP), - buildInfo(MAIN_USER_ID, "app2", 0 /* flags */), - buildInfo(MAIN_USER_ID, "app3", ApplicationInfo.FLAG_SYSTEM), - buildInfo(MAIN_USER_ID, "app4", ApplicationInfo.FLAG_SYSTEM))); + buildInfo(MAIN_USER_ID, APP_1, ApplicationInfo.FLAG_UPDATED_SYSTEM_APP), + buildInfo(MAIN_USER_ID, APP_2, 0 /* flags */), + buildInfo(MAIN_USER_ID, APP_3, ApplicationInfo.FLAG_SYSTEM), + buildInfo(MAIN_USER_ID, APP_4, ApplicationInfo.FLAG_SYSTEM))); // For system apps, InstalledAppCounter checks whether they handle the default launcher // intent to decide whether to include them in the count of installed apps or not. - expectQueryIntentActivities(MAIN_USER_ID, "app3", true /* launchable */); - expectQueryIntentActivities(MAIN_USER_ID, "app4", false /* launchable */); + expectQueryIntentActivities(MAIN_USER_ID, APP_3, true /* launchable */); + expectQueryIntentActivities(MAIN_USER_ID, APP_4, false /* launchable */); + + // app1, app3 and app4 are installed by enterprise policy. + final UserHandle mainUser = new UserHandle(MAIN_USER_ID); + when(mPackageManager.getInstallReason(APP_1, mainUser)) + .thenReturn(PackageManager.INSTALL_REASON_POLICY); + when(mPackageManager.getInstallReason(APP_2, mainUser)) + .thenReturn(PackageManager.INSTALL_REASON_UNKNOWN); + when(mPackageManager.getInstallReason(APP_3, mainUser)) + .thenReturn(PackageManager.INSTALL_REASON_POLICY); + when(mPackageManager.getInstallReason(APP_4, mainUser)) + .thenReturn(PackageManager.INSTALL_REASON_POLICY); // The second user has four apps installed: // * app5 is a user-installed app. It should be counted. @@ -116,12 +135,21 @@ public final class InstalledAppCounterTest { when(mPackageManager.getInstalledApplicationsAsUser(PackageManager.GET_DISABLED_COMPONENTS | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, MANAGED_PROFILE_ID)).thenReturn(Arrays.asList( - buildInfo(MANAGED_PROFILE_ID, "app5", 0 /* flags */), - buildInfo(MANAGED_PROFILE_ID, "app6", ApplicationInfo.FLAG_SYSTEM))); - expectQueryIntentActivities(MANAGED_PROFILE_ID, "app6", true /* launchable */); + buildInfo(MANAGED_PROFILE_ID, APP_5, 0 /* flags */), + buildInfo(MANAGED_PROFILE_ID, APP_6, ApplicationInfo.FLAG_SYSTEM))); + expectQueryIntentActivities(MANAGED_PROFILE_ID, APP_6, true /* launchable */); - // Count the number of apps installed. Wait for the background task to finish. - (new InstalledAppCounterTestable()).execute(); + // app5 is installed by enterprise policy. + final UserHandle managedProfileUser = new UserHandle(MANAGED_PROFILE_ID); + when(mPackageManager.getInstallReason(APP_5, managedProfileUser)) + .thenReturn(PackageManager.INSTALL_REASON_POLICY); + when(mPackageManager.getInstallReason(APP_6, managedProfileUser)) + .thenReturn(PackageManager.INSTALL_REASON_UNKNOWN); + + // Count the number of all apps installed, irrespective of install reason. Wait for the + // background task to finish. + (new InstalledAppCounterTestable(ApplicationFeatureProvider.IGNORE_INSTALL_REASON)) + .execute(); ShadowApplication.runBackgroundTasks(); assertThat(mInstalledAppCount).isEqualTo(5); @@ -134,11 +162,19 @@ public final class InstalledAppCounterTest { verify(mPackageManager, atLeast(0)).queryIntentActivitiesAsUser(anyObject(), anyInt(), anyInt()); verifyNoMoreInteractions(mPackageManager); + + // Count once more, considering apps installed by enterprise policy only. Wait for the + // background task to finish. + mInstalledAppCount = 0; + (new InstalledAppCounterTestable(PackageManager.INSTALL_REASON_POLICY)).execute(); + ShadowApplication.runBackgroundTasks(); + + assertThat(mInstalledAppCount).isEqualTo(3); } private class InstalledAppCounterTestable extends InstalledAppCounter { - public InstalledAppCounterTestable() { - super(mContext, mPackageManager); + public InstalledAppCounterTestable(int installReason) { + super(mContext, installReason, mPackageManager); } @Override diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java new file mode 100644 index 00000000000..9a46e1428c2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/enterprise/EnterpriseInstalledPackagesPreferenceControllerTest.java @@ -0,0 +1,113 @@ +/* + * 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 com.android.settings.enterprise; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.support.v7.preference.Preference; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settings.R; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.applications.ApplicationFeatureProvider; +import com.android.settings.testutils.FakeFeatureFactory; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.robolectric.annotation.Config; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.anyObject; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.when; + +/** + * Tests for {@link EnterpriseInstalledPackagesPreferenceController}. + */ +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public final class EnterpriseInstalledPackagesPreferenceControllerTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + private FakeFeatureFactory mFeatureFactory; + + private EnterpriseInstalledPackagesPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + FakeFeatureFactory.setupForTest(mContext); + mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext); + mController = new EnterpriseInstalledPackagesPreferenceController(mContext); + } + + private void setNumberOfEnterpriseInstalledPackages(int number) { + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) { + ((ApplicationFeatureProvider.NumberOfInstalledAppsCallback) + invocation.getArguments()[1]).onNumberOfInstalledAppsResult(number); + return null; + }}).when(mFeatureFactory.applicationFeatureProvider) + .calculateNumberOfInstalledApps(eq(PackageManager.INSTALL_REASON_POLICY), + anyObject()); + } + + @Test + public void testUpdateState() { + final Preference preference = new Preference(mContext, null, 0, 0); + preference.setVisible(true); + + setNumberOfEnterpriseInstalledPackages(20); + when(mContext.getResources().getQuantityString( + R.plurals.enterprise_privacy_number_enterprise_installed_packages, 20, 20)) + .thenReturn("20 packages"); + mController.updateState(preference); + assertThat(preference.getTitle()).isEqualTo("20 packages"); + assertThat(preference.isVisible()).isTrue(); + + setNumberOfEnterpriseInstalledPackages(0); + mController.updateState(preference); + assertThat(preference.isVisible()).isFalse(); + } + + @Test + public void testIsAvailable() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void testHandlePreferenceTreeClick() { + assertThat(mController.handlePreferenceTreeClick(new Preference(mContext, null, 0, 0))) + .isFalse(); + } + + @Test + public void testGetPreferenceKey() { + assertThat(mController.getPreferenceKey()) + .isEqualTo("number_enterprise_installed_packages"); + } +} diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java index 40222efc248..5e4e08f4702 100644 --- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java @@ -73,7 +73,7 @@ public final class EnterprisePrivacySettingsTest { final List controllers = mSettings.getPreferenceControllers( ShadowApplication.getInstance().getApplicationContext()); assertThat(controllers).isNotNull(); - assertThat(controllers.size()).isEqualTo(7); + assertThat(controllers.size()).isEqualTo(8); assertThat(controllers.get(0)).isInstanceOf(InstalledPackagesPreferenceController.class); assertThat(controllers.get(1)).isInstanceOf(NetworkLogsPreferenceController.class); assertThat(controllers.get(2)).isInstanceOf(BugReportsPreferenceController.class); @@ -83,6 +83,7 @@ public final class EnterprisePrivacySettingsTest { assertThat(controllers.get(5)).isInstanceOf( AlwaysOnVpnManagedProfilePreferenceController.class); assertThat(controllers.get(6)).isInstanceOf(GlobalHttpProxyPreferenceController.class); - + assertThat(controllers.get(7)).isInstanceOf( + EnterpriseInstalledPackagesPreferenceController.class); } } diff --git a/tests/robotests/src/com/android/settings/enterprise/InstalledPackagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/InstalledPackagesPreferenceControllerTest.java index 79db853c83b..5a0da66288a 100644 --- a/tests/robotests/src/com/android/settings/enterprise/InstalledPackagesPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/InstalledPackagesPreferenceControllerTest.java @@ -40,6 +40,7 @@ import org.robolectric.annotation.Config; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.anyObject; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.eq; import static org.mockito.Mockito.when; /** @@ -69,10 +70,11 @@ public final class InstalledPackagesPreferenceControllerTest { doAnswer(new Answer() { public Object answer(InvocationOnMock invocation) { ((ApplicationFeatureProvider.NumberOfInstalledAppsCallback) - invocation.getArguments()[0]).onNumberOfInstalledAppsResult(20); + invocation.getArguments()[1]).onNumberOfInstalledAppsResult(20); return null; }}).when(mFeatureFactory.applicationFeatureProvider) - .calculateNumberOfInstalledApps(anyObject()); + .calculateNumberOfInstalledApps( + eq(ApplicationFeatureProvider.IGNORE_INSTALL_REASON), anyObject()); when(mContext.getResources().getQuantityString( R.plurals.enterprise_privacy_number_installed_packages, 20, 20)) .thenReturn("20 packages");