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

Commit d546f620 authored by Anna Zappone's avatar Anna Zappone
Browse files

Expose new PeopleService API for People Tiles

Avoid over-querying data by returning a single ConversationChannel when
requested by shortcut ID.

Test: DataManagerTest
Change-Id: I181682b70022d1ce0b055ce1e7c97f5b84c6f1f0
parent 752b1e59
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2021, 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 android.app.people;

parcelable ConversationChannel;
 No newline at end of file
+8 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.app.people;

import android.app.people.ConversationStatus;
import android.app.people.ConversationChannel;
import android.content.pm.ParceledListSlice;
import android.net.Uri;
import android.os.IBinder;
@@ -26,6 +27,13 @@ import android.os.IBinder;
 * {@hide}
 */
interface IPeopleManager {

    /**
    * Returns the specified conversation from the conversations list. If the conversation can't be
    * found, returns null.
    */
    ConversationChannel getConversation(in String packageName, int userId, in String shortcutId);

    /**
     * Returns the recent conversations. The conversations that have customized notification
     * settings are excluded from the returned list.
+7 −1
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.people.data.DataManager;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@@ -155,6 +154,13 @@ public class PeopleService extends SystemService {

    final IBinder mService = new IPeopleManager.Stub() {

        @Override
        public ConversationChannel getConversation(
                String packageName, int userId, String shortcutId) {
            enforceSystemRootOrSystemUI(getContext(), "get conversation");
            return mDataManager.getConversation(packageName, userId, shortcutId);
        }

        @Override
        public ParceledListSlice<ConversationChannel> getRecentConversations() {
            enforceSystemRootOrSystemUI(getContext(), "get recent conversations");
+48 −16
Original line number Diff line number Diff line
@@ -222,33 +222,65 @@ public class DataManager {
                mContext.getPackageName(), intentFilter, callingUserId);
    }

    /**
     * Returns a {@link ConversationChannel} with the associated {@code shortcutId} if existent.
     * Otherwise, returns null.
     */
    @Nullable
    public ConversationChannel getConversation(String packageName, int userId, String shortcutId) {
        UserData userData = getUnlockedUserData(userId);
        if (userData != null) {
            PackageData packageData = userData.getPackageData(packageName);
            // App may have been uninstalled.
            if (packageData != null) {
                return getConversationChannel(packageData, shortcutId);
            }
        }
        return null;
    }

    @Nullable
    private ConversationChannel getConversationChannel(PackageData packageData, String shortcutId) {
        ConversationInfo conversationInfo = packageData.getConversationInfo(shortcutId);
        if (conversationInfo == null) {
            return null;
        }
        int userId = packageData.getUserId();
        String packageName = packageData.getPackageName();
        ShortcutInfo shortcutInfo = getShortcut(packageName, userId, shortcutId);
        if (shortcutInfo == null) {
            return null;
        }
        int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
        NotificationChannel parentChannel =
                mNotificationManagerInternal.getNotificationChannel(packageName, uid,
                        conversationInfo.getParentNotificationChannelId());
        NotificationChannelGroup parentChannelGroup = null;
        if (parentChannel != null) {
            parentChannelGroup =
                    mNotificationManagerInternal.getNotificationChannelGroup(packageName,
                            uid, parentChannel.getId());
        }
        return new ConversationChannel(shortcutInfo, uid, parentChannel,
                parentChannelGroup,
                conversationInfo.getLastEventTimestamp(),
                hasActiveNotifications(packageName, userId, shortcutId));
    }

    /** Returns the cached non-customized recent conversations. */
    public List<ConversationChannel> getRecentConversations(@UserIdInt int callingUserId) {
        List<ConversationChannel> conversationChannels = new ArrayList<>();
        forPackagesInProfile(callingUserId, packageData -> {
            String packageName = packageData.getPackageName();
            int userId = packageData.getUserId();
            packageData.forAllConversations(conversationInfo -> {
                if (!isCachedRecentConversation(conversationInfo)) {
                    return;
                }
                String shortcutId = conversationInfo.getShortcutId();
                ShortcutInfo shortcutInfo = getShortcut(packageName, userId, shortcutId);
                int uid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
                NotificationChannel parentChannel =
                        mNotificationManagerInternal.getNotificationChannel(packageName, uid,
                                conversationInfo.getParentNotificationChannelId());
                if (shortcutInfo == null || parentChannel == null) {
                ConversationChannel channel = getConversationChannel(packageData, shortcutId);
                if (channel == null || channel.getParentNotificationChannel() == null) {
                    return;
                }
                NotificationChannelGroup parentChannelGroup =
                        mNotificationManagerInternal.getNotificationChannelGroup(packageName,
                                uid, parentChannel.getId());
                conversationChannels.add(
                        new ConversationChannel(shortcutInfo, uid, parentChannel,
                                parentChannelGroup,
                                conversationInfo.getLastEventTimestamp(),
                                hasActiveNotifications(packageName, userId, shortcutId)));
                conversationChannels.add(channel);
            });
        });
        return conversationChannels;
+79 −0
Original line number Diff line number Diff line
@@ -514,6 +514,85 @@ public final class DataManagerTest {
        assertTrue(mDataManager.getRecentConversations(USER_ID_PRIMARY).isEmpty());
    }

    @Test
    public void testGetConversationReturnsCustomizedConversation() {
        mDataManager.onUserUnlocked(USER_ID_PRIMARY);

        ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
                buildPerson());
        mDataManager.addOrUpdateConversationInfo(shortcut);

        NotificationListenerService listenerService =
                mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);

        listenerService.onNotificationPosted(mStatusBarNotification);
        shortcut.setCached(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS);
        mDataManager.addOrUpdateConversationInfo(shortcut);

        assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
                TEST_SHORTCUT_ID)).isNotNull();

        listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY),
                mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);

        assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
                TEST_SHORTCUT_ID)).isNotNull();
    }

    @Test
    public void testGetConversation() {
        mDataManager.onUserUnlocked(USER_ID_PRIMARY);
        assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
            TEST_SHORTCUT_ID)).isNull();

        ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
                buildPerson());
        shortcut.setCached(ShortcutInfo.FLAG_PINNED);
        mDataManager.addOrUpdateConversationInfo(shortcut);
        assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
            TEST_SHORTCUT_ID)).isNotNull();
        assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
                TEST_SHORTCUT_ID + "1")).isNull();

        NotificationListenerService listenerService =
                mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
        listenerService.onNotificationPosted(mStatusBarNotification);

        ConversationChannel result = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
                TEST_SHORTCUT_ID);
        assertThat(result).isNotNull();
        assertEquals(shortcut.getId(), result.getShortcutInfo().getId());
        assertEquals(1, result.getShortcutInfo().getPersons().length);
        assertEquals(CONTACT_URI, result.getShortcutInfo().getPersons()[0].getUri());
        assertEquals(mParentNotificationChannel.getId(),
                result.getParentNotificationChannel().getId());
        assertEquals(mStatusBarNotification.getPostTime(), result.getLastEventTimestamp());
        assertTrue(result.hasActiveNotifications());
    }

    @Test
    public void testGetConversationGetsPersonsData() {
        mDataManager.onUserUnlocked(USER_ID_PRIMARY);

        ShortcutInfo shortcut = buildShortcutInfo(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID,
                buildPerson());
        shortcut.setCached(ShortcutInfo.FLAG_PINNED);
        mDataManager.addOrUpdateConversationInfo(shortcut);

        NotificationListenerService listenerService =
                mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
        listenerService.onNotificationPosted(mStatusBarNotification);

        ConversationChannel result = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
                TEST_SHORTCUT_ID);

        verify(mShortcutServiceInternal).getShortcuts(
                anyInt(), anyString(), anyLong(), anyString(), anyList(), any(), any(),
                mQueryFlagsCaptor.capture(), anyInt(), anyInt(), anyInt());
        Integer queryFlags = mQueryFlagsCaptor.getValue();
        assertThat(hasFlag(queryFlags, ShortcutQuery.FLAG_GET_PERSONS_DATA)).isTrue();
    }

    @Test
    public void testNotificationChannelCreated() {
        mDataManager.onUserUnlocked(USER_ID_PRIMARY);