Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6de947c8 authored by Anna Zappone's avatar Anna Zappone
Browse files

Update on shortcut changes and statuses cleared

Test: DataManagerTest
Bug: 178792356
Change-Id: I75499d7fe856222499689ef4b5c5be1c064211a9
parent 502c7548
Loading
Loading
Loading
Loading
+53 −16
Original line number Diff line number Diff line
@@ -111,7 +111,8 @@ public class DataManager {
    private static final long RECENT_NOTIFICATIONS_MAX_AGE_MS = 10 * DateUtils.DAY_IN_MILLIS;
    private static final long QUERY_EVENTS_MAX_AGE_MS = 5L * DateUtils.MINUTE_IN_MILLIS;
    private static final long USAGE_STATS_QUERY_INTERVAL_SEC = 120L;
    @VisibleForTesting static final int MAX_CACHED_RECENT_SHORTCUTS = 30;
    @VisibleForTesting
    static final int MAX_CACHED_RECENT_SHORTCUTS = 30;

    private final Context mContext;
    private final Injector mInjector;
@@ -256,14 +257,23 @@ public class DataManager {
    @Nullable
    private ConversationChannel getConversationChannel(String packageName, int userId,
            String shortcutId, ConversationInfo conversationInfo) {
        ShortcutInfo shortcutInfo = getShortcut(packageName, userId, shortcutId);
        return getConversationChannel(shortcutInfo, conversationInfo);
    }

    @Nullable
    private ConversationChannel getConversationChannel(ShortcutInfo shortcutInfo,
            ConversationInfo conversationInfo) {
        if (conversationInfo == null) {
            return null;
        }
        ShortcutInfo shortcutInfo = getShortcut(packageName, userId, shortcutId);
        if (shortcutInfo == null) {
            Slog.e(TAG, " Shortcut no longer found: " + shortcutId);
            Slog.e(TAG, " Shortcut no longer found");
            return null;
        }
        String packageName = shortcutInfo.getPackage();
        String shortcutId = shortcutInfo.getId();
        int userId = shortcutInfo.getUserId();
        int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
        NotificationChannel parentChannel =
                mNotificationManagerInternal.getNotificationChannel(packageName, uid,
@@ -363,7 +373,9 @@ public class DataManager {
                    }
                }
                builder.setStatuses(newStatuses);
                cs.addOrUpdate(builder.build());
                updateConversationStoreThenNotifyListeners(cs, builder.build(),
                        packageData.getPackageName(),
                        packageData.getUserId());
            });
        });
    }
@@ -397,11 +409,7 @@ public class DataManager {
        ConversationInfo convToModify = getConversationInfoOrThrow(cs, conversationId);
        ConversationInfo.Builder builder = new ConversationInfo.Builder(convToModify);
        builder.addOrUpdateStatus(status);
        ConversationInfo modifiedConv = builder.build();
        cs.addOrUpdate(modifiedConv);
        ConversationChannel conversation = getConversationChannel(packageName, userId,
                conversationId, modifiedConv);
        notifyConversationsListeners(Arrays.asList(conversation));
        updateConversationStoreThenNotifyListeners(cs, builder.build(), packageName, userId);

        if (status.getEndTimeMillis() >= 0) {
            mStatusExpReceiver.scheduleExpiration(
@@ -416,7 +424,7 @@ public class DataManager {
        ConversationInfo convToModify = getConversationInfoOrThrow(cs, conversationId);
        ConversationInfo.Builder builder = new ConversationInfo.Builder(convToModify);
        builder.clearStatus(statusId);
        cs.addOrUpdate(builder.build());
        updateConversationStoreThenNotifyListeners(cs, builder.build(), packageName, userId);
    }

    public void clearStatuses(String packageName, int userId, String conversationId) {
@@ -424,7 +432,7 @@ public class DataManager {
        ConversationInfo convToModify = getConversationInfoOrThrow(cs, conversationId);
        ConversationInfo.Builder builder = new ConversationInfo.Builder(convToModify);
        builder.setStatuses(null);
        cs.addOrUpdate(builder.build());
        updateConversationStoreThenNotifyListeners(cs, builder.build(), packageName, userId);
    }

    public @NonNull List<ConversationStatus> getStatuses(String packageName, int userId,
@@ -882,7 +890,8 @@ public class DataManager {
                }
            }
        }
        conversationStore.addOrUpdate(builder.build());
        updateConversationStoreThenNotifyListeners(conversationStore, builder.build(),
                shortcutInfo);
    }

    @VisibleForTesting
@@ -945,6 +954,7 @@ public class DataManager {
                    conversationSelector.mConversationStore =
                            packageData.getConversationStore();
                    conversationSelector.mConversationInfo = ci;
                    conversationSelector.mPackageName = packageData.getPackageName();
                }
            });
            if (conversationSelector.mConversationInfo == null) {
@@ -955,13 +965,16 @@ public class DataManager {
                    new ConversationInfo.Builder(conversationSelector.mConversationInfo);
            builder.setContactStarred(helper.isStarred());
            builder.setContactPhoneNumber(helper.getPhoneNumber());
            conversationSelector.mConversationStore.addOrUpdate(builder.build());
            updateConversationStoreThenNotifyListeners(conversationSelector.mConversationStore,
                    builder.build(),
                    conversationSelector.mPackageName, userId);
            mLastUpdatedTimestamp = helper.getLastUpdatedTimestamp();
        }

        private class ConversationSelector {
            private ConversationStore mConversationStore = null;
            private ConversationInfo mConversationInfo = null;
            private String mPackageName = null;
        }
    }

@@ -1140,6 +1153,7 @@ public class DataManager {
                        .setLastEventTimestamp(sbn.getPostTime())
                        .setParentNotificationChannelId(sbn.getNotification().getChannelId())
                        .build();
                // Don't update listeners on notifications posted.
                packageData.getConversationStore().addOrUpdate(updated);

                EventHistoryImpl eventHistory = packageData.getEventStore().getOrCreateEventHistory(
@@ -1215,7 +1229,8 @@ public class DataManager {
                    builder.setBubbled(false);
                    break;
            }
            conversationStore.addOrUpdate(builder.build());
            updateConversationStoreThenNotifyListeners(conversationStore, builder.build(), pkg,
                    packageData.getUserId());
        }

        synchronized boolean hasActiveNotifications(String packageName, String shortcutId) {
@@ -1253,7 +1268,9 @@ public class DataManager {
                ConversationInfo updated = new ConversationInfo.Builder(conversationInfo)
                        .setLastEventTimestamp(event.getTimestamp())
                        .build();
                packageData.getConversationStore().addOrUpdate(updated);
                updateConversationStoreThenNotifyListeners(packageData.getConversationStore(),
                        updated,
                        packageData.getPackageName(), packageData.getUserId());
            }
        }
    }
@@ -1266,7 +1283,27 @@ public class DataManager {
        }
    }

    // TODO(b/178792356): Trigger ConversationsListener on all-related data changes.
    private void updateConversationStoreThenNotifyListeners(ConversationStore cs,
            ConversationInfo modifiedConv,
            String packageName, int userId) {
        cs.addOrUpdate(modifiedConv);
        ConversationChannel channel = getConversationChannel(packageName, userId,
                modifiedConv.getShortcutId(), modifiedConv);
        if (channel != null) {
            notifyConversationsListeners(Arrays.asList(channel));
        }
    }

    private void updateConversationStoreThenNotifyListeners(ConversationStore cs,
            ConversationInfo modifiedConv, ShortcutInfo shortcutInfo) {
        cs.addOrUpdate(modifiedConv);
        ConversationChannel channel = getConversationChannel(shortcutInfo, modifiedConv);
        if (channel != null) {
            notifyConversationsListeners(Arrays.asList(channel));
        }
    }


    @VisibleForTesting
    void notifyConversationsListeners(
            @Nullable final List<ConversationChannel> changedConversations) {
+80 −20
Original line number Diff line number Diff line
@@ -135,24 +135,41 @@ public final class DataManagerTest {
    private static final String PARENT_NOTIFICATION_CHANNEL_ID = "test";
    private static final long MILLIS_PER_MINUTE = 1000L * 60L;

    @Mock private Context mContext;
    @Mock private ShortcutServiceInternal mShortcutServiceInternal;
    @Mock private UsageStatsManagerInternal mUsageStatsManagerInternal;
    @Mock private PackageManagerInternal mPackageManagerInternal;
    @Mock private NotificationManagerInternal mNotificationManagerInternal;
    @Mock private UserManager mUserManager;
    @Mock private PackageManager mPackageManager;
    @Mock private TelephonyManager mTelephonyManager;
    @Mock private TelecomManager mTelecomManager;
    @Mock private ContentResolver mContentResolver;
    @Mock private JobScheduler mJobScheduler;
    @Mock private StatusBarNotification mStatusBarNotification;
    @Mock private Notification mNotification;
    @Mock private AlarmManager mAlarmManager;

    @Captor private ArgumentCaptor<ShortcutChangeCallback> mShortcutChangeCallbackCaptor;
    @Captor private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
    @Captor private ArgumentCaptor<Integer> mQueryFlagsCaptor;
    @Mock
    private Context mContext;
    @Mock
    private ShortcutServiceInternal mShortcutServiceInternal;
    @Mock
    private UsageStatsManagerInternal mUsageStatsManagerInternal;
    @Mock
    private PackageManagerInternal mPackageManagerInternal;
    @Mock
    private NotificationManagerInternal mNotificationManagerInternal;
    @Mock
    private UserManager mUserManager;
    @Mock
    private PackageManager mPackageManager;
    @Mock
    private TelephonyManager mTelephonyManager;
    @Mock
    private TelecomManager mTelecomManager;
    @Mock
    private ContentResolver mContentResolver;
    @Mock
    private JobScheduler mJobScheduler;
    @Mock
    private StatusBarNotification mStatusBarNotification;
    @Mock
    private Notification mNotification;
    @Mock
    private AlarmManager mAlarmManager;

    @Captor
    private ArgumentCaptor<ShortcutChangeCallback> mShortcutChangeCallbackCaptor;
    @Captor
    private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
    @Captor
    private ArgumentCaptor<Integer> mQueryFlagsCaptor;

    private ScheduledExecutorService mExecutorService;
    private NotificationChannel mNotificationChannel;
@@ -556,6 +573,7 @@ public final class DataManagerTest {
                TEST_SHORTCUT_ID_2,
                buildPerson());
        mDataManager.addOrUpdateConversationInfo(shortcut2);
        mLooper.dispatchAll();
        ConversationChannel conversationChannel2 = mDataManager.getConversation(TEST_PKG_NAME,
                USER_ID_PRIMARY,
                TEST_SHORTCUT_ID_2);
@@ -583,6 +601,7 @@ public final class DataManagerTest {
        ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
                buildPerson());
        mDataManager.addOrUpdateConversationInfo(shortcut);
        mLooper.dispatchAll();
        PeopleService.ConversationsListener listener = mock(
                PeopleService.ConversationsListener.class);
        mDataManager.addConversationsListener(listener);
@@ -781,16 +800,25 @@ public final class DataManagerTest {
    @Test
    public void testShortcutAddedOrUpdated() {
        mDataManager.onUserUnlocked(USER_ID_PRIMARY);
        PeopleService.ConversationsListener listener = mock(
                PeopleService.ConversationsListener.class);
        mDataManager.addConversationsListener(listener);

        ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
                buildPerson());
        mShortcutChangeCallback.onShortcutsAddedOrUpdated(TEST_PKG_NAME,
                Collections.singletonList(shortcut), UserHandle.of(USER_ID_PRIMARY));
        mLooper.dispatchAll();

        List<ConversationInfo> conversations = getConversationsInPrimary();

        assertEquals(1, conversations.size());
        assertEquals(TEST_SHORTCUT_ID, conversations.get(0).getShortcutId());
        ArgumentCaptor<List<ConversationChannel>> capturedConversation = ArgumentCaptor.forClass(
                List.class);
        verify(listener, times(1)).onConversationsUpdate(capturedConversation.capture());
        ConversationChannel result = Iterables.getOnlyElement(capturedConversation.getValue());
        assertEquals(result.getShortcutInfo().getId(), TEST_SHORTCUT_ID);
    }

    @Test
@@ -978,8 +1006,13 @@ public final class DataManagerTest {
        mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs1);
        mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs2);
        mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs3);
        mLooper.dispatchAll();

        PeopleService.ConversationsListener listener = mock(
                PeopleService.ConversationsListener.class);
        mDataManager.addConversationsListener(listener);
        mDataManager.pruneDataForUser(USER_ID_PRIMARY, mCancellationSignal);
        mLooper.dispatchAll();

        assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
                .doesNotContain(cs1);
@@ -987,6 +1020,13 @@ public final class DataManagerTest {
                .contains(cs2);
        assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
                .contains(cs3);
        ArgumentCaptor<List<ConversationChannel>> capturedConversation = ArgumentCaptor.forClass(
                List.class);
        verify(listener, times(1)).onConversationsUpdate(capturedConversation.capture());
        List<ConversationChannel> results = capturedConversation.getValue();
        ConversationChannel result = Iterables.getOnlyElement(capturedConversation.getValue());
        // CHeck cs1 has been removed and only cs2 and cs3 remain.
        assertThat(result.getStatuses()).containsExactly(cs2, cs3);
    }

    @Test
@@ -1236,13 +1276,23 @@ public final class DataManagerTest {
        ConversationStatus cs2 = new ConversationStatus.Builder("id2", ACTIVITY_GAME).build();
        mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs);
        mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs2);
        mLooper.dispatchAll();

        PeopleService.ConversationsListener listener = mock(
                PeopleService.ConversationsListener.class);
        mDataManager.addConversationsListener(listener);
        mDataManager.clearStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs2.getId());
        mLooper.dispatchAll();

        assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
                .contains(cs);
        assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
                .doesNotContain(cs2);
        ArgumentCaptor<List<ConversationChannel>> capturedConversation = ArgumentCaptor.forClass(
                List.class);
        verify(listener, times(1)).onConversationsUpdate(capturedConversation.capture());
        ConversationChannel result = Iterables.getOnlyElement(capturedConversation.getValue());
        assertThat(result.getStatuses()).containsExactly(cs);
    }

    @Test
@@ -1257,11 +1307,21 @@ public final class DataManagerTest {
        ConversationStatus cs2 = new ConversationStatus.Builder("id2", ACTIVITY_GAME).build();
        mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs);
        mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs2);
        mLooper.dispatchAll();

        PeopleService.ConversationsListener listener = mock(
                PeopleService.ConversationsListener.class);
        mDataManager.addConversationsListener(listener);
        mDataManager.clearStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID);
        mLooper.dispatchAll();

        assertThat(mDataManager.getStatuses(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID))
                .isEmpty();
        ArgumentCaptor<List<ConversationChannel>> capturedConversation = ArgumentCaptor.forClass(
                List.class);
        verify(listener, times(1)).onConversationsUpdate(capturedConversation.capture());
        ConversationChannel result = Iterables.getOnlyElement(capturedConversation.getValue());
        assertThat(result.getStatuses()).isEmpty();
    }

    @Test