From 1d07be390b106243b82954cd187c55063946cd41 Mon Sep 17 00:00:00 2001 From: Tony Mak Date: Wed, 2 Jan 2019 15:14:32 +0000 Subject: [PATCH] TYPE_DATE and TYPE_DATE_TIME should be considered as the same type To avoid confusion, we already suppress actions of the same entity type. But from the user perspective, some entity types are really the same thing, like TYPE_DATE and TYPE_DATE_TIME. This is just a workaround before moving to suggestConversationActions for smart actions. Once we have moved to it, both TYPE_DATE and TYPE_DATE_TIME entities should be mapped to the same action type --- OPEN_CALENDAR. FIXES: 121200744 Test: atest EntityTypeCounterTest Test: Try out a notification with both TYPE_DATE and TYPE_DATE_TIME entities, observes that both actions are not shown. Change-Id: Id1c91bff5749c62be29a2da0cc9ed7fd8960d166 --- .../notification/EntityTypeCounter.java | 73 +++++++++++++++++++ .../notification/SmartActionsHelper.java | 26 +------ .../notification/EntityTypeCounterTest.java | 58 +++++++++++++++ 3 files changed, 133 insertions(+), 24 deletions(-) create mode 100644 packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java create mode 100644 packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java diff --git a/packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java b/packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java new file mode 100644 index 0000000000000..50cb0abd63297 --- /dev/null +++ b/packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2018 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.ext.services.notification; + +import android.annotation.NonNull; +import android.util.ArrayMap; +import android.view.textclassifier.TextClassifier; +import android.view.textclassifier.TextLinks; + +/** + * Counts the entity types for smart actions. Some entity types are considered the same + * type, like {@link TextClassifier#TYPE_DATE} and {@link TextClassifier#TYPE_DATE_TIME}. + */ +class EntityTypeCounter { + + private static final ArrayMap ENTITY_TYPE_MAPPING = new ArrayMap<>(); + + static { + ENTITY_TYPE_MAPPING.put(TextClassifier.TYPE_DATE_TIME, TextClassifier.TYPE_DATE); + } + + private final ArrayMap mEntityTypeCount = new ArrayMap<>(); + + + void increment(@NonNull String entityType) { + entityType = convertToBaseEntityType(entityType); + if (mEntityTypeCount.containsKey(entityType)) { + mEntityTypeCount.put(entityType, mEntityTypeCount.get(entityType) + 1); + } else { + mEntityTypeCount.put(entityType, 1); + } + } + + int getCount(@NonNull String entityType) { + entityType = convertToBaseEntityType(entityType); + return mEntityTypeCount.getOrDefault(entityType, 0); + } + + @NonNull + private String convertToBaseEntityType(@NonNull String entityType) { + return ENTITY_TYPE_MAPPING.getOrDefault(entityType, entityType); + } + + /** + * Given the links extracted from a piece of text, returns the frequency of each entity + * type. + */ + @NonNull + static EntityTypeCounter fromTextLinks(@NonNull TextLinks links) { + EntityTypeCounter counter = new EntityTypeCounter(); + for (TextLinks.TextLink link : links.getLinks()) { + if (link.getEntityCount() == 0) { + continue; + } + String entityType = link.getEntity(0); + counter.increment(entityType); + } + return counter; + } +} diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java index b041842c45b92..56c415816558f 100644 --- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java +++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java @@ -26,7 +26,6 @@ import android.os.Parcelable; import android.os.Process; import android.service.notification.NotificationAssistantService; import android.text.TextUtils; -import android.util.ArrayMap; import android.util.LruCache; import android.view.textclassifier.ConversationActions; import android.view.textclassifier.TextClassification; @@ -356,7 +355,7 @@ public class SmartActionsHelper { TextClassifier.HINT_TEXT_IS_NOT_EDITABLE))) .build(); TextLinks links = mTextClassifier.generateLinks(textLinksRequest); - ArrayMap entityTypeFrequency = getEntityTypeFrequency(links); + EntityTypeCounter entityTypeCounter = EntityTypeCounter.fromTextLinks(links); ArrayList actions = new ArrayList<>(); for (TextLinks.TextLink link : links.getLinks()) { @@ -364,7 +363,7 @@ public class SmartActionsHelper { // case where a notification contains e.g. a list of phone numbers. In such cases, the // user likely wants to act on the whole list rather than an individual entity. if (link.getEntityCount() == 0 - || entityTypeFrequency.get(link.getEntity(0)) != 1) { + || entityTypeCounter.getCount(link.getEntity(0)) != 1) { continue; } @@ -398,25 +397,4 @@ public class SmartActionsHelper { } return actions; } - - /** - * Given the links extracted from a piece of text, returns the frequency of each entity - * type. - */ - @NonNull - private ArrayMap getEntityTypeFrequency(@NonNull TextLinks links) { - ArrayMap entityTypeCount = new ArrayMap<>(); - for (TextLinks.TextLink link : links.getLinks()) { - if (link.getEntityCount() == 0) { - continue; - } - String entityType = link.getEntity(0); - if (entityTypeCount.containsKey(entityType)) { - entityTypeCount.put(entityType, entityTypeCount.get(entityType) + 1); - } else { - entityTypeCount.put(entityType, 1); - } - } - return entityTypeCount; - } } diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java new file mode 100644 index 0000000000000..2d29c7b77759b --- /dev/null +++ b/packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2018 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.ext.services.notification; + +import static com.google.common.truth.Truth.assertThat; + +import android.support.test.runner.AndroidJUnit4; +import android.view.textclassifier.TextClassifier; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class EntityTypeCounterTest { + private EntityTypeCounter mCounter; + + @Before + public void setup() { + mCounter = new EntityTypeCounter(); + } + + @Test + public void testIncrementAndGetCount() { + mCounter.increment(TextClassifier.TYPE_URL); + mCounter.increment(TextClassifier.TYPE_URL); + mCounter.increment(TextClassifier.TYPE_URL); + + mCounter.increment(TextClassifier.TYPE_PHONE); + mCounter.increment(TextClassifier.TYPE_PHONE); + + assertThat(mCounter.getCount(TextClassifier.TYPE_URL)).isEqualTo(3); + assertThat(mCounter.getCount(TextClassifier.TYPE_PHONE)).isEqualTo(2); + assertThat(mCounter.getCount(TextClassifier.TYPE_DATE_TIME)).isEqualTo(0); + } + + @Test + public void testIncrementAndGetCount_typeDateAndDateTime() { + mCounter.increment(TextClassifier.TYPE_DATE_TIME); + mCounter.increment(TextClassifier.TYPE_DATE); + + assertThat(mCounter.getCount(TextClassifier.TYPE_DATE_TIME)).isEqualTo(2); + assertThat(mCounter.getCount(TextClassifier.TYPE_DATE)).isEqualTo(2); + } +}