diff --git a/src/com/android/settings/applications/AppStateNotificationBridge.java b/src/com/android/settings/applications/AppStateNotificationBridge.java index a96a3b1ad7b..6cf64c3e57b 100644 --- a/src/com/android/settings/applications/AppStateNotificationBridge.java +++ b/src/com/android/settings/applications/AppStateNotificationBridge.java @@ -15,9 +15,13 @@ */ package com.android.settings.applications; +import android.app.usage.IUsageStatsManager; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager; import android.content.Context; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.UserManager; import android.text.format.DateUtils; import android.util.ArrayMap; import android.view.View; @@ -25,6 +29,7 @@ import android.view.ViewGroup; import android.widget.Switch; import com.android.settings.R; +import com.android.settings.Utils; import com.android.settings.notification.NotificationBackend; import com.android.settingslib.applications.ApplicationsState; import com.android.settingslib.applications.ApplicationsState.AppEntry; @@ -33,6 +38,7 @@ import com.android.settingslib.utils.StringUtil; import java.util.ArrayList; import java.util.Comparator; +import java.util.List; import java.util.Map; /** @@ -42,17 +48,24 @@ import java.util.Map; public class AppStateNotificationBridge extends AppStateBaseBridge { private final Context mContext; - private UsageStatsManager mUsageStatsManager; + private IUsageStatsManager mUsageStatsManager; + protected List mUserIds; private NotificationBackend mBackend; private static final int DAYS_TO_CHECK = 7; public AppStateNotificationBridge(Context context, ApplicationsState appState, - Callback callback, UsageStatsManager usageStatsManager, - NotificationBackend backend) { + Callback callback, IUsageStatsManager usageStatsManager, + UserManager userManager, NotificationBackend backend) { super(appState, callback); mContext = context; mUsageStatsManager = usageStatsManager; mBackend = backend; + mUserIds = new ArrayList<>(); + mUserIds.add(mContext.getUserId()); + int workUserId = Utils.getManagedProfileId(userManager, mContext.getUserId()); + if (workUserId != UserHandle.USER_NULL) { + mUserIds.add(workUserId); + } } @Override @@ -62,7 +75,8 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { final Map map = getAggregatedUsageEvents(); for (AppEntry entry : apps) { - NotificationsSentState stats = map.get(entry.info.packageName); + NotificationsSentState stats = + map.get(getKey(UserHandle.getUserId(entry.info.uid), entry.info.packageName)); calculateAvgSentCounts(stats); addBlockStatus(entry, stats); entry.extraInfo = stats; @@ -71,8 +85,8 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { @Override protected void updateExtraInfo(AppEntry entry, String pkg, int uid) { - Map map = getAggregatedUsageEvents(); - NotificationsSentState stats = map.get(entry.info.packageName); + NotificationsSentState stats = getAggregatedUsageEvents( + UserHandle.getUserId(entry.info.uid), entry.info.packageName); calculateAvgSentCounts(stats); addBlockStatus(entry, stats); entry.extraInfo = stats; @@ -116,18 +130,59 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { long now = System.currentTimeMillis(); long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK); - UsageEvents events = mUsageStatsManager.queryEvents(startTime, now); + for (int userId : mUserIds) { + UsageEvents events = null; + try { + events = mUsageStatsManager.queryEventsForUser( + startTime, now, userId, mContext.getPackageName()); + } catch (RemoteException e) { + e.printStackTrace(); + } + if (events != null) { + UsageEvents.Event event = new UsageEvents.Event(); + while (events.hasNextEvent()) { + events.getNextEvent(event); + NotificationsSentState stats = + aggregatedStats.get(getKey(userId, event.getPackageName())); + if (stats == null) { + stats = new NotificationsSentState(); + aggregatedStats.put(getKey(userId, event.getPackageName()), stats); + } + + if (event.getEventType() == UsageEvents.Event.NOTIFICATION_INTERRUPTION) { + if (event.getTimeStamp() > stats.lastSent) { + stats.lastSent = event.getTimeStamp(); + } + stats.sentCount++; + } + + } + } + } + return aggregatedStats; + } + + protected NotificationsSentState getAggregatedUsageEvents(int userId, String pkg) { + NotificationsSentState stats = null; + + long now = System.currentTimeMillis(); + long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK); + UsageEvents events = null; + try { + events = mUsageStatsManager.queryEventsForPackageForUser( + startTime, now, userId, pkg, mContext.getPackageName()); + } catch (RemoteException e) { + e.printStackTrace(); + } if (events != null) { UsageEvents.Event event = new UsageEvents.Event(); while (events.hasNextEvent()) { events.getNextEvent(event); - NotificationsSentState stats = aggregatedStats.get(event.getPackageName()); - if (stats == null) { - stats = new NotificationsSentState(); - aggregatedStats.put(event.getPackageName(), stats); - } if (event.getEventType() == UsageEvents.Event.NOTIFICATION_INTERRUPTION) { + if (stats == null) { + stats = new NotificationsSentState(); + } if (event.getTimeStamp() > stats.lastSent) { stats.lastSent = event.getTimeStamp(); } @@ -136,7 +191,7 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { } } - return aggregatedStats; + return stats; } private static NotificationsSentState getNotificationsSentState(AppEntry entry) { @@ -149,6 +204,10 @@ public class AppStateNotificationBridge extends AppStateBaseBridge { return null; } + protected static String getKey(int userId, String pkg) { + return userId + "|" + pkg; + } + public View.OnClickListener getSwitchOnClickListener(final AppEntry entry) { if (entry != null) { return v -> { diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index 2250f285c23..dc9214e59b1 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -41,6 +41,7 @@ import static com.android.settings.applications.manageapplications.AppFilterRegi import android.annotation.Nullable; import android.annotation.StringRes; import android.app.Activity; +import android.app.usage.IUsageStatsManager; import android.app.usage.UsageStatsManager; import android.content.Context; import android.content.Intent; @@ -48,6 +49,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageItemInfo; import android.os.Bundle; import android.os.Environment; +import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.preference.PreferenceFrameLayout; @@ -224,7 +226,8 @@ public class ManageApplications extends InstrumentedFragment private View mSpinnerHeader; private Spinner mFilterSpinner; private FilterSpinnerAdapter mFilterAdapter; - private UsageStatsManager mUsageStatsManager; + private IUsageStatsManager mUsageStatsManager; + private UserManager mUserManager; private NotificationBackend mNotificationBackend; private ResetAppsHelper mResetAppsHelper; private String mVolumeUuid; @@ -294,8 +297,9 @@ public class ManageApplications extends InstrumentedFragment screenTitle = R.string.change_wifi_state_title; } else if (className.equals(Settings.NotificationAppListActivity.class.getName())) { mListType = LIST_TYPE_NOTIFICATION; - mUsageStatsManager = - (UsageStatsManager) getContext().getSystemService(Context.USAGE_STATS_SERVICE); + mUsageStatsManager = IUsageStatsManager.Stub.asInterface( + ServiceManager.getService(Context.USAGE_STATS_SERVICE)); + mUserManager = UserManager.get(getContext()); mNotificationBackend = new NotificationBackend(); mSortOrder = R.id.sort_order_recent_notification; screenTitle = R.string.app_notifications_title; @@ -889,6 +893,7 @@ public class ManageApplications extends InstrumentedFragment if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) { mExtraInfoBridge = new AppStateNotificationBridge(mContext, mState, this, manageApplications.mUsageStatsManager, + manageApplications.mUserManager, manageApplications.mNotificationBackend); } else if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) { mExtraInfoBridge = new AppStateUsageBridge(mContext, mState, this); diff --git a/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java b/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java index 9437a00766f..8e3bb4254a0 100644 --- a/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java @@ -36,17 +36,21 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.usage.IUsageStatsManager; import android.app.usage.UsageEvents; import android.app.usage.UsageEvents.Event; -import android.app.usage.UsageStatsManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.os.Looper; import android.os.Parcel; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.UserManager; import android.view.ViewGroup; import android.widget.Switch; @@ -79,7 +83,9 @@ public class AppStateNotificationBridgeTest { @Mock private ApplicationsState mState; @Mock - private UsageStatsManager mUsageStats; + private IUsageStatsManager mUsageStats; + @Mock + private UserManager mUserManager; @Mock private NotificationBackend mBackend; private Context mContext; @@ -92,10 +98,12 @@ public class AppStateNotificationBridgeTest { when(mState.getBackgroundLooper()).thenReturn(mock(Looper.class)); when(mBackend.getNotificationsBanned(anyString(), anyInt())).thenReturn(true); when(mBackend.isSystemApp(any(), any())).thenReturn(true); + // most tests assume no work profile + when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{}); mContext = RuntimeEnvironment.application.getApplicationContext(); mBridge = new AppStateNotificationBridge(mContext, mState, - mock(AppStateBaseBridge.Callback.class), mUsageStats, mBackend); + mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend); } private AppEntry getMockAppEntry(String pkg) { @@ -115,14 +123,15 @@ public class AppStateNotificationBridgeTest { } @Test - public void testGetAggregatedUsageEvents_noEvents() { - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class)); + public void testGetAggregatedUsageEvents_noEvents() throws Exception { + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(mock(UsageEvents.class)); assertThat(mBridge.getAggregatedUsageEvents()).isEmpty(); } @Test - public void testGetAggregatedUsageEvents_onlyNotificationEvents() { + public void testGetAggregatedUsageEvents_onlyNotificationEvents() throws Exception { List events = new ArrayList<>(); Event good = new Event(); good.mEventType = Event.NOTIFICATION_INTERRUPTION; @@ -136,14 +145,15 @@ public class AppStateNotificationBridgeTest { events.add(bad); UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); Map map = mBridge.getAggregatedUsageEvents(); - assertThat(map.get(PKG1).sentCount).isEqualTo(1); + assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(1); } @Test - public void testGetAggregatedUsageEvents_multipleEventsAgg() { + public void testGetAggregatedUsageEvents_multipleEventsAgg() throws Exception { List events = new ArrayList<>(); Event good = new Event(); good.mEventType = Event.NOTIFICATION_INTERRUPTION; @@ -157,15 +167,16 @@ public class AppStateNotificationBridgeTest { events.add(good1); UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); Map map = mBridge.getAggregatedUsageEvents(); - assertThat(map.get(PKG1).sentCount).isEqualTo(2); - assertThat(map.get(PKG1).lastSent).isEqualTo(6); + assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(2); + assertThat(map.get(mBridge.getKey(0, PKG1)).lastSent).isEqualTo(6); } @Test - public void testGetAggregatedUsageEvents_multiplePkgs() { + public void testGetAggregatedUsageEvents_multiplePkgs() throws Exception { List events = new ArrayList<>(); Event good = new Event(); good.mEventType = Event.NOTIFICATION_INTERRUPTION; @@ -179,19 +190,21 @@ public class AppStateNotificationBridgeTest { events.add(good1); UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); Map map = mBridge.getAggregatedUsageEvents(); - assertThat(map.get(PKG1).sentCount).isEqualTo(1); - assertThat(map.get(PKG2).sentCount).isEqualTo(1); - assertThat(map.get(PKG1).lastSent).isEqualTo(6); - assertThat(map.get(PKG2).lastSent).isEqualTo(1); + assertThat(map.get(mBridge.getKey(0, PKG1)).sentCount).isEqualTo(1); + assertThat(map.get(mBridge.getKey(0, PKG2)).sentCount).isEqualTo(1); + assertThat(map.get(mBridge.getKey(0, PKG1)).lastSent).isEqualTo(6); + assertThat(map.get(mBridge.getKey(0, PKG2)).lastSent).isEqualTo(1); } @Test - public void testLoadAllExtraInfo_noEvents() { - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class)); + public void testLoadAllExtraInfo_noEvents() throws RemoteException { + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(mock(UsageEvents.class)); ArrayList apps = new ArrayList<>(); apps.add(getMockAppEntry(PKG1)); when(mSession.getAllApps()).thenReturn(apps); @@ -201,7 +214,7 @@ public class AppStateNotificationBridgeTest { } @Test - public void testLoadAllExtraInfo_multipleEventsAgg() { + public void testLoadAllExtraInfo_multipleEventsAgg() throws RemoteException { List events = new ArrayList<>(); for (int i = 0; i < 7; i++) { Event good = new Event(); @@ -212,7 +225,8 @@ public class AppStateNotificationBridgeTest { } UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); ArrayList apps = new ArrayList<>(); apps.add(getMockAppEntry(PKG1)); @@ -229,7 +243,7 @@ public class AppStateNotificationBridgeTest { } @Test - public void testLoadAllExtraInfo_multiplePkgs() { + public void testLoadAllExtraInfo_multiplePkgs() throws RemoteException { List events = new ArrayList<>(); for (int i = 0; i < 8; i++) { Event good = new Event(); @@ -245,7 +259,8 @@ public class AppStateNotificationBridgeTest { events.add(good1); UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString())) + .thenReturn(usageEvents); ArrayList apps = new ArrayList<>(); apps.add(getMockAppEntry(PKG1)); @@ -265,8 +280,66 @@ public class AppStateNotificationBridgeTest { } @Test - public void testUpdateExtraInfo_noEvents() { - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class)); + public void testLoadAllExtraInfo_multipleUsers() throws RemoteException { + // has work profile + when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{1}); + mBridge = new AppStateNotificationBridge(mContext, mState, + mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend); + + List eventsProfileOwner = new ArrayList<>(); + for (int i = 0; i < 8; i++) { + Event good = new Event(); + good.mEventType = Event.NOTIFICATION_INTERRUPTION; + good.mPackage = PKG1; + good.mTimeStamp = i; + eventsProfileOwner.add(good); + } + + List eventsProfile = new ArrayList<>(); + for (int i = 0; i < 4; i++) { + Event good = new Event(); + good.mEventType = Event.NOTIFICATION_INTERRUPTION; + good.mPackage = PKG1; + good.mTimeStamp = i; + eventsProfile.add(good); + } + + UsageEvents usageEventsOwner = getUsageEvents(eventsProfileOwner); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(0), anyString())) + .thenReturn(usageEventsOwner); + + UsageEvents usageEventsProfile = getUsageEvents(eventsProfile); + when(mUsageStats.queryEventsForUser(anyLong(), anyLong(), eq(1), anyString())) + .thenReturn(usageEventsProfile); + + ArrayList apps = new ArrayList<>(); + AppEntry owner = getMockAppEntry(PKG1); + owner.info.uid = 1; + apps.add(owner); + + AppEntry profile = getMockAppEntry(PKG1); + profile.info.uid = UserHandle.PER_USER_RANGE + 1; + apps.add(profile); + when(mSession.getAllApps()).thenReturn(apps); + + mBridge.loadAllExtraInfo(); + + assertThat(((NotificationsSentState) apps.get(0).extraInfo).sentCount).isEqualTo(8); + assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(7); + assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentWeekly).isEqualTo(0); + assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(1); + + assertThat(((NotificationsSentState) apps.get(1).extraInfo).sentCount).isEqualTo(4); + assertThat(((NotificationsSentState) apps.get(1).extraInfo).lastSent).isEqualTo(3); + assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentWeekly).isEqualTo(4); + assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentDaily).isEqualTo(1); + } + + @Test + public void testUpdateExtraInfo_noEvents() throws RemoteException { + when(mUsageStats.queryEventsForPackageForUser( + anyLong(), anyLong(), anyInt(), anyString(), anyString())) + .thenReturn(mock(UsageEvents.class)); AppEntry entry = getMockAppEntry(PKG1); mBridge.updateExtraInfo(entry, "", 0); @@ -274,7 +347,7 @@ public class AppStateNotificationBridgeTest { } @Test - public void testUpdateExtraInfo_multipleEventsAgg() { + public void testUpdateExtraInfo_multipleEventsAgg() throws RemoteException { List events = new ArrayList<>(); for (int i = 0; i < 13; i++) { Event good = new Event(); @@ -285,7 +358,8 @@ public class AppStateNotificationBridgeTest { } UsageEvents usageEvents = getUsageEvents(events); - when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents); + when(mUsageStats.queryEventsForPackageForUser( + anyLong(), anyLong(), anyInt(), anyString(), anyString())).thenReturn(usageEvents); AppEntry entry = getMockAppEntry(PKG1); mBridge.updateExtraInfo(entry, "", 0); diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java index af297c4d9c2..8943d72ad33 100644 --- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java +++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java @@ -16,14 +16,14 @@ package com.android.settings.applications.manageapplications; -import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING; -import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE; -import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL; -import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN; -import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION; -import static com.google.common.truth.Truth.assertThat; +import static com.android.settings.applications.manageapplications.AppFilterRegistry + .FILTER_APPS_ALL; +import static com.android.settings.applications.manageapplications.ManageApplications + .LIST_TYPE_MAIN; +import static com.android.settings.applications.manageapplications.ManageApplications + .LIST_TYPE_NOTIFICATION; -import static junit.framework.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Matchers.any; @@ -36,11 +36,14 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING; +import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE; + import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.Looper; -import androidx.recyclerview.widget.RecyclerView; +import android.os.UserManager; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -63,6 +66,8 @@ import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; +import androidx.recyclerview.widget.RecyclerView; + @RunWith(SettingsRobolectricTestRunner.class) public class ManageApplicationsTest { @@ -272,6 +277,10 @@ public class ManageApplicationsTest { @Test public void applicationsAdapter_onBindViewHolder_updateSwitch_notifications() { ManageApplications manageApplications = mock(ManageApplications.class); + when(manageApplications.getActivity()).thenReturn(mock(Activity.class)); + UserManager um = mock(UserManager.class); + when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{}); + ReflectionHelpers.setField(manageApplications, "mUserManager", um); manageApplications.mListType = LIST_TYPE_NOTIFICATION; ApplicationViewHolder holder = mock(ApplicationViewHolder.class); ReflectionHelpers.setField(holder, "itemView", mock(View.class)); @@ -293,6 +302,9 @@ public class ManageApplicationsTest { manageApplications.mListType = LIST_TYPE_MAIN; ApplicationViewHolder holder = mock(ApplicationViewHolder.class); ReflectionHelpers.setField(holder, "itemView", mock(View.class)); + UserManager um = mock(UserManager.class); + when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{}); + ReflectionHelpers.setField(manageApplications, "mUserManager", um); ManageApplications.ApplicationsAdapter adapter = new ManageApplications.ApplicationsAdapter(mState, manageApplications, mock(AppFilterItem.class), @@ -308,6 +320,10 @@ public class ManageApplicationsTest { @Test public void sortOrderSavedOnRebuild() { ManageApplications manageApplications = mock(ManageApplications.class); + when(manageApplications.getActivity()).thenReturn(mock(Activity.class)); + UserManager um = mock(UserManager.class); + when(um.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{}); + ReflectionHelpers.setField(manageApplications, "mUserManager", um); manageApplications.mListType = LIST_TYPE_NOTIFICATION; manageApplications.mSortOrder = -1; ManageApplications.ApplicationsAdapter adapter =