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

Commit 0dd99e0c authored by Anna Zappone's avatar Anna Zappone Committed by Android (Google) Code Review
Browse files

Merge "Update on shortcut changes and statuses cleared" into sc-dev

parents 5a96ceaf 6de947c8
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