From e091cef8624b1f6686c5425858c0399f4fefce5c Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Mon, 24 Oct 2016 17:21:42 -0700 Subject: [PATCH] Show "uninstall for all users" when >1 users installed it. Bug: 32167081 Test: make SettingsTests Change-Id: I407549838d40c160a84a36f2d9ebaa8dc73d6008 --- .../applications/InstalledAppDetails.java | 34 +++++++ .../applications/PackageUtilTest.java | 93 +++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 tests/app/src/com/android/settings/applications/PackageUtilTest.java diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index 38d4f4992e1..948220c3255 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -53,6 +53,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.service.notification.NotificationListenerService.Ranking; +import android.support.annotation.VisibleForTesting; import android.support.v7.preference.Preference; import android.support.v7.preference.Preference.OnPreferenceClickListener; import android.support.v7.preference.PreferenceCategory; @@ -461,6 +462,8 @@ public class InstalledAppDetails extends AppInfoBase showIt = false; } else if (mUserManager.getUsers().size() < 2) { showIt = false; + } else if (PackageUtil.countPackageInUsers(mPm, mUserManager, mPackageName) < 2) { + showIt = false; } menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(showIt); mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; @@ -1164,6 +1167,37 @@ public class InstalledAppDetails extends AppInfoBase } } + /** + * Elicit this class for testing. Test cannot be done in robolectric because it + * invokes the new API. + */ + @VisibleForTesting + public static class PackageUtil { + /** + * Count how many users in device have installed package {@paramref packageName} + */ + public static int countPackageInUsers(PackageManager packageManager, UserManager + userManager, String packageName) { + final List userInfos = userManager.getUsers(true); + int count = 0; + + for (final UserInfo userInfo : userInfos) { + try { + // Use this API to check whether user has this package + final ApplicationInfo info = packageManager.getApplicationInfoAsUser( + packageName, PackageManager.GET_META_DATA, userInfo.id); + if ((info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) { + count++; + } + } catch(NameNotFoundException e) { + Log.e(TAG, "Package: " + packageName + " not found for user: " + userInfo.id); + } + } + + return count; + } + } + private static class DisableChanger extends AsyncTask { final PackageManager mPm; final WeakReference mActivity; diff --git a/tests/app/src/com/android/settings/applications/PackageUtilTest.java b/tests/app/src/com/android/settings/applications/PackageUtilTest.java new file mode 100644 index 00000000000..1c064ae8897 --- /dev/null +++ b/tests/app/src/com/android/settings/applications/PackageUtilTest.java @@ -0,0 +1,93 @@ +/* + * 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.settings.applications; + +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.UserInfo; +import android.os.UserManager; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; +import java.util.List; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.Mockito.when; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class PackageUtilTest { + private static final String ALL_USERS_APP_NAME = "com.google.allusers.app"; + private static final String ONE_USER_APP_NAME = "com.google.oneuser.app"; + private static final int USER1_ID = 1; + private static final int USER2_ID = 11; + + @Mock + private PackageManager mMockPackageManager; + @Mock + private UserManager mMockUserManager; + + private InstalledAppDetails.PackageUtil mPackageUtil; + private List mUserInfos; + + @Before + public void setUp() throws PackageManager.NameNotFoundException { + MockitoAnnotations.initMocks(this); + + mUserInfos = new ArrayList<>(); + mUserInfos.add(new UserInfo(USER1_ID, "lei", 0)); + mUserInfos.add(new UserInfo(USER2_ID, "yue", 0)); + when(mMockUserManager.getUsers(true)).thenReturn(mUserInfos); + + ApplicationInfo usersApp = new ApplicationInfo(); + usersApp.flags = ApplicationInfo.FLAG_INSTALLED; + + when(mMockPackageManager.getApplicationInfoAsUser( + ALL_USERS_APP_NAME, PackageManager.GET_META_DATA, USER1_ID)) + .thenReturn(usersApp); + when(mMockPackageManager.getApplicationInfoAsUser( + ALL_USERS_APP_NAME, PackageManager.GET_META_DATA, USER2_ID)) + .thenReturn(usersApp); + + when(mMockPackageManager.getApplicationInfoAsUser( + ONE_USER_APP_NAME, PackageManager.GET_META_DATA, USER1_ID)) + .thenReturn(usersApp); + + when(mMockPackageManager.getApplicationInfoAsUser( + ONE_USER_APP_NAME, PackageManager.GET_META_DATA, USER2_ID)) + .thenThrow(new PackageManager.NameNotFoundException()); + + mPackageUtil = new InstalledAppDetails.PackageUtil(); + } + + @Test + public void testCountPackageInUsers_twoUsersInstalled_returnTwo() { + assertEquals(2, mPackageUtil.countPackageInUsers( + mMockPackageManager, mMockUserManager, ALL_USERS_APP_NAME)); + } + + @Test + public void testCountPackageInUsers_oneUsersInstalled_returnOne() { + assertEquals(1, mPackageUtil.countPackageInUsers( + mMockPackageManager, mMockUserManager, ONE_USER_APP_NAME)); + } +}