diff options
| author | 2021-01-25 14:29:16 +0000 | |
|---|---|---|
| committer | 2021-01-29 14:49:55 +0000 | |
| commit | 30ebaa214af27b10b262124cb90f714bbae1b578 (patch) | |
| tree | d1786473e762e6463ca2c5df6a3d72f3381ec308 | |
| parent | 59050b0853e8d3277b72ecccacf699d19f32b23a (diff) | |
Expose new PeopleService API for People Tiles
Avoid over-querying data by returning a single ConversationChannel when
requested by shortcut ID.
Test: DataManagerTest
Bug: 178792356
Change-Id: I181682b70022d1ce0b055ce1e7c97f5b84c6f1f0
(cherry picked from commit d546f6206372ece3ce65451c24f0bc097f6e966f)
5 files changed, 161 insertions, 17 deletions
diff --git a/core/java/android/app/people/ConversationChannel.aidl b/core/java/android/app/people/ConversationChannel.aidl new file mode 100644 index 000000000000..78df2f10c337 --- /dev/null +++ b/core/java/android/app/people/ConversationChannel.aidl @@ -0,0 +1,19 @@ +/** + * 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 diff --git a/core/java/android/app/people/IPeopleManager.aidl b/core/java/android/app/people/IPeopleManager.aidl index 0d12ed02f610..ebe9f60dc150 100644 --- a/core/java/android/app/people/IPeopleManager.aidl +++ b/core/java/android/app/people/IPeopleManager.aidl @@ -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. diff --git a/services/people/java/com/android/server/people/PeopleService.java b/services/people/java/com/android/server/people/PeopleService.java index 091e688743dd..5453de14a5f1 100644 --- a/services/people/java/com/android/server/people/PeopleService.java +++ b/services/people/java/com/android/server/people/PeopleService.java @@ -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; @@ -156,6 +155,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"); return new ParceledListSlice<>( diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java index 752141598c9d..9a9a17112245 100644 --- a/services/people/java/com/android/server/people/data/DataManager.java +++ b/services/people/java/com/android/server/people/data/DataManager.java @@ -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; diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java index 63330d518297..161d3163c1cf 100644 --- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java @@ -515,6 +515,85 @@ public final class DataManagerTest { } @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); mDataManager.onUserUnlocked(USER_ID_SECONDARY); |