Merge "add unit tests for the atom puller" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-06-01 21:09:43 +00:00
committed by Android (Google) Code Review
6 changed files with 389 additions and 47 deletions

View File

@@ -1952,7 +1952,8 @@ public class NotificationManagerService extends SystemService {
mRankingHandler,
mZenModeHelper,
new NotificationChannelLoggerImpl(),
mAppOps);
mAppOps,
new SysUiStatsEvent.BuilderFactory());
mRankingHelper = new RankingHelper(getContext(),
mRankingHandler,
mPreferencesHelper,

View File

@@ -140,6 +140,7 @@ public class PreferencesHelper implements RankingConfig {
* fields.
*/
private static final int DEFAULT_LOCKED_APP_FIELDS = 0;
private final SysUiStatsEvent.BuilderFactory mStatsEventBuilderFactory;
/**
* All user-lockable fields for a given application.
@@ -171,13 +172,15 @@ public class PreferencesHelper implements RankingConfig {
public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger,
AppOpsManager appOpsManager) {
AppOpsManager appOpsManager,
SysUiStatsEvent.BuilderFactory statsEventBuilderFactory) {
mContext = context;
mZenModeHelper = zenHelper;
mRankingHandler = rankingHandler;
mPm = pm;
mNotificationChannelLogger = notificationChannelLogger;
mAppOps = appOpsManager;
mStatsEventBuilderFactory = statsEventBuilderFactory;
updateBadgingEnabled();
updateBubblesEnabled();
@@ -1898,7 +1901,7 @@ public class PreferencesHelper implements RankingConfig {
if (i > NOTIFICATION_PREFERENCES_PULL_LIMIT) {
break;
}
StatsEvent.Builder event = StatsEvent.newBuilder()
SysUiStatsEvent.Builder event = mStatsEventBuilderFactory.newBuilder()
.setAtomId(PACKAGE_NOTIFICATION_PREFERENCES);
final PackagePreferences r = mPackagePreferences.valueAt(i);
event.writeInt(r.uid);
@@ -1927,7 +1930,7 @@ public class PreferencesHelper implements RankingConfig {
if (++totalChannelsPulled > NOTIFICATION_CHANNEL_PULL_LIMIT) {
break;
}
StatsEvent.Builder event = StatsEvent.newBuilder()
SysUiStatsEvent.Builder event = mStatsEventBuilderFactory.newBuilder()
.setAtomId(PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES);
event.writeInt(r.uid);
event.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
@@ -1962,7 +1965,7 @@ public class PreferencesHelper implements RankingConfig {
if (++totalGroupsPulled > NOTIFICATION_CHANNEL_GROUP_PULL_LIMIT) {
break;
}
StatsEvent.Builder event = StatsEvent.newBuilder()
SysUiStatsEvent.Builder event = mStatsEventBuilderFactory.newBuilder()
.setAtomId(PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES);
event.writeInt(r.uid);
event.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2020 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 com.android.server.notification;
import android.util.StatsEvent;
/**
* Wrapper for StatsEvent that enables unit testing.
*/
public class SysUiStatsEvent {
static class Builder {
private final StatsEvent.Builder mBuilder;
protected Builder(StatsEvent.Builder builder) {
mBuilder = builder;
}
public StatsEvent build() {
return mBuilder.build();
}
public Builder setAtomId(int atomId) {
mBuilder.setAtomId(atomId);
return this;
}
public Builder writeInt(int value) {
mBuilder.writeInt(value);
return this;
}
public Builder addBooleanAnnotation(byte annotation, boolean value) {
mBuilder.addBooleanAnnotation(annotation, value);
return this;
}
public Builder writeString(String value) {
mBuilder.writeString(value);
return this;
}
public Builder writeBoolean(boolean value) {
mBuilder.writeBoolean(value);
return this;
}
}
static class BuilderFactory {
Builder newBuilder() {
return new Builder(StatsEvent.newBuilder());
}
}
}

View File

@@ -21,6 +21,7 @@ android_test {
"mockito-target-inline-minus-junit4",
"platform-test-annotations",
"platformprotosnano",
"statsdprotolite",
"hamcrest-library",
"testables",
"truth-prebuilt",

View File

@@ -29,6 +29,16 @@ import static android.app.NotificationManager.IMPORTANCE_MAX;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_IS_UID;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.CHANNEL_ID_FIELD_NUMBER;
import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.CHANNEL_NAME_FIELD_NUMBER;
import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IMPORTANCE_FIELD_NUMBER;
import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_CONVERSATION_FIELD_NUMBER;
import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_DELETED_FIELD_NUMBER;
import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_DEMOTED_CONVERSATION_FIELD_NUMBER;
import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.IS_IMPORTANT_CONVERSATION_FIELD_NUMBER;
import static com.android.os.AtomsProto.PackageNotificationChannelPreferences.UID_FIELD_NUMBER;
import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE;
import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
import static com.android.server.notification.PreferencesHelper.UNKNOWN_UID;
@@ -91,7 +101,6 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.UiServiceTestCase;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
@@ -110,6 +119,7 @@ import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -146,6 +156,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
private PreferencesHelper mHelper;
private AudioAttributes mAudioAttributes;
private NotificationChannelLoggerFake mLogger = new NotificationChannelLoggerFake();
private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory;
@Before
public void setUp() throws Exception {
@@ -197,8 +208,11 @@ public class PreferencesHelperTest extends UiServiceTestCase {
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(),
anyString(), eq(null), anyString())).thenReturn(MODE_DEFAULT);
mStatsEventBuilderFactory = new WrappedSysUiStatsEvent.WrappedBuilderFactory();
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
resetZenModeHelper();
mAudioAttributes = new AudioAttributes.Builder()
@@ -1483,7 +1497,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
assertFalse(mHelper.areChannelsBypassingDnd());
verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
resetZenModeHelper();
@@ -1495,7 +1509,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
assertFalse(mHelper.areChannelsBypassingDnd());
verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
resetZenModeHelper();
@@ -2262,7 +2276,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
+ "</package>\n"
+ "</ranking>\n";
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
@@ -2275,7 +2289,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
@@ -2372,7 +2386,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2384,7 +2398,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2397,7 +2411,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2410,7 +2424,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
// appears disabled
@@ -2429,7 +2443,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
// appears disabled
@@ -2448,7 +2462,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
@@ -2503,7 +2517,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
@@ -2540,7 +2554,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
@@ -3019,31 +3033,6 @@ public class PreferencesHelperTest extends UiServiceTestCase {
PKG_O, UID_O, parent.getId(), conversationId, false, false), conversationId);
}
@Test
public void testPullConversationNotificationChannel() {
String conversationId = "friend";
NotificationChannel parent =
new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
String channelId = String.format(
CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId);
NotificationChannel friend = new NotificationChannel(channelId,
"messages", IMPORTANCE_DEFAULT);
friend.setConversationId(parent.getId(), conversationId);
mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
boolean found = false;
for (StatsEvent event : events) {
// TODO(b/153195691): inspect the content once it is possible to do so
found = true;
}
assertTrue("conversation was not in the pull", found);
}
@Test
public void testGetNotificationChannel_conversationProvidedByNotCustomizedYet() {
String conversationId = "friend";
@@ -3077,7 +3066,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testPlaceholderConversationId_shortcutRequired() throws Exception {
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
final String xml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -3096,7 +3085,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testNormalConversationId_shortcutRequired() throws Exception {
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
final String xml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -3115,7 +3104,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testNoConversationId_shortcutRequired() throws Exception {
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
mAppOpsManager, mStatsEventBuilderFactory);
final String xml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -3477,4 +3466,151 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.setValidMessageSent(PKG_P, UID_P);
assertFalse(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
}
@Test
public void testPullPackageChannelPreferencesStats() {
String channelId = "parent";
String name = "messages";
NotificationChannel fodderA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
mHelper.createNotificationChannel(PKG_O, UID_O, fodderA, true, false);
NotificationChannel channel =
new NotificationChannel(channelId, name, IMPORTANCE_DEFAULT);
mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
NotificationChannel fodderB = new NotificationChannel("b", "b", IMPORTANCE_HIGH);
mHelper.createNotificationChannel(PKG_O, UID_O, fodderB, true, false);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
int found = 0;
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
&& channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
++found;
assertEquals("uid", UID_O, builder.getValue(UID_FIELD_NUMBER));
assertTrue("uid annotation", builder.getBooleanAnnotation(
UID_FIELD_NUMBER, ANNOTATION_ID_IS_UID));
assertEquals("importance", IMPORTANCE_DEFAULT, builder.getValue(
IMPORTANCE_FIELD_NUMBER));
assertEquals("name", name, builder.getValue(CHANNEL_NAME_FIELD_NUMBER));
assertFalse("isconv", builder.getBoolean(IS_CONVERSATION_FIELD_NUMBER));
assertFalse("deleted", builder.getBoolean(IS_DELETED_FIELD_NUMBER));
}
}
}
@Test
public void testPullPackageChannelPreferencesStats_one_to_one() {
NotificationChannel channelA = new NotificationChannel("a", "a", IMPORTANCE_LOW);
mHelper.createNotificationChannel(PKG_O, UID_O, channelA, true, false);
NotificationChannel channelB = new NotificationChannel("b", "b", IMPORTANCE_LOW);
mHelper.createNotificationChannel(PKG_O, UID_O, channelB, true, false);
NotificationChannel channelC = new NotificationChannel("c", "c", IMPORTANCE_HIGH);
mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false);
List<String> channels = new LinkedList<>(Arrays.asList("a", "b", "c"));
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
int found = 0;
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES) {
Object id = builder.getValue(CHANNEL_ID_FIELD_NUMBER);
assertTrue("missing channel in the output", channels.contains(id));
channels.remove(id);
}
}
assertTrue("unexpected channel in output", channels.isEmpty());
}
@Test
public void testPullPackageChannelPreferencesStats_conversation() {
String conversationId = "friend";
NotificationChannel parent =
new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
String channelId = String.format(
CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), conversationId);
String name = "conversation";
NotificationChannel friend = new NotificationChannel(channelId,
name, IMPORTANCE_DEFAULT);
friend.setConversationId(parent.getId(), conversationId);
mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
&& channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
assertTrue("isConveration should be true", builder.getBoolean(
IS_CONVERSATION_FIELD_NUMBER));
assertFalse("not demoted", builder.getBoolean(
IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
assertFalse("not important", builder.getBoolean(
IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
}
}
}
@Test
public void testPullPackageChannelPreferencesStats_conversation_demoted() {
NotificationChannel parent =
new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
String channelId = String.format(
CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
NotificationChannel friend = new NotificationChannel(channelId,
"conversation", IMPORTANCE_DEFAULT);
friend.setConversationId(parent.getId(), "friend");
friend.setDemoted(true);
mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
&& channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
assertTrue("isConveration should be true", builder.getBoolean(
IS_CONVERSATION_FIELD_NUMBER));
assertTrue("is demoted", builder.getBoolean(
IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
assertFalse("not important", builder.getBoolean(
IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
}
}
}
@Test
public void testPullPackageChannelPreferencesStats_conversation_priority() {
NotificationChannel parent =
new NotificationChannel("parent", "messages", IMPORTANCE_DEFAULT);
mHelper.createNotificationChannel(PKG_O, UID_O, parent, true, false);
String channelId = String.format(
CONVERSATION_CHANNEL_ID_FORMAT, parent.getId(), "friend");
NotificationChannel friend = new NotificationChannel(channelId,
"conversation", IMPORTANCE_DEFAULT);
friend.setConversationId(parent.getId(), "friend");
friend.setImportantConversation(true);
mHelper.createNotificationChannel(PKG_O, UID_O, friend, true, false);
ArrayList<StatsEvent> events = new ArrayList<>();
mHelper.pullPackageChannelPreferencesStats(events);
for (WrappedSysUiStatsEvent.WrappedBuilder builder : mStatsEventBuilderFactory.builders) {
if (builder.getAtomId() == PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES
&& channelId.equals(builder.getValue(CHANNEL_ID_FIELD_NUMBER))) {
assertTrue("isConveration should be true", builder.getBoolean(
IS_CONVERSATION_FIELD_NUMBER));
assertFalse("not demoted", builder.getBoolean(
IS_DEMOTED_CONVERSATION_FIELD_NUMBER));
assertTrue("is important", builder.getBoolean(
IS_IMPORTANT_CONVERSATION_FIELD_NUMBER));
}
}
}
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (C) 2020 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 com.android.server.notification;
import android.util.StatsEvent;
import com.android.server.notification.SysUiStatsEvent.Builder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Wrapper for SysUiStatsEvent that implements validation.
*/
public class WrappedSysUiStatsEvent {
static class WrappedBuilder extends Builder {
private ArrayList<Object> mValues;
private HashMap<Integer, HashMap<Byte, Object>> mAnnotations;
private int mAtomId;
private int mLastIndex;
private boolean mBuilt;
WrappedBuilder(StatsEvent.Builder builder) {
super(builder);
mValues = new ArrayList<>();
mAnnotations = new HashMap<>();
mValues.add(0); // proto fields are 1-based
}
@Override
public Builder setAtomId(int atomId) {
mAtomId = atomId;
super.setAtomId(atomId);
return this;
}
@Override
public Builder writeInt(int value) {
addValue(Integer.valueOf(value));
super.writeInt(value);
return this;
}
@Override
public Builder addBooleanAnnotation(byte annotation, boolean value) {
addAnnotation(annotation, Boolean.valueOf(value));
super.addBooleanAnnotation(annotation, value);
return this;
}
@Override
public Builder writeString(String value) {
addValue(value);
super.writeString(value);
return this;
}
@Override
public Builder writeBoolean(boolean value) {
addValue(Boolean.valueOf(value));
super.writeBoolean(value);
return this;
}
@Override
public StatsEvent build() {
mBuilt = true;
return super.build();
}
public Object getValue(int index) {
return index < mValues.size() ? mValues.get(index) : null;
}
/** useful to make assertTrue() statemetns more readable. */
public boolean getBoolean(int index) {
return (Boolean) mValues.get(index);
}
private void addValue(Object value) {
mLastIndex = mValues.size();
mValues.add(value);
}
private void addAnnotation(byte annotation, Object value) {
Integer key = Integer.valueOf(mLastIndex);
if (!mAnnotations.containsKey(key)) {
mAnnotations.put(key, new HashMap<>());
}
mAnnotations.get(key).put(Byte.valueOf(annotation), value);
}
public boolean getBooleanAnnotation(int i, byte a) {
return ((Boolean) mAnnotations.get(Integer.valueOf(i)).get(Byte.valueOf(a)))
.booleanValue();
}
public int getAtomId() {
return mAtomId;
}
}
static class WrappedBuilderFactory extends SysUiStatsEvent.BuilderFactory {
public List<WrappedBuilder> builders;
WrappedBuilderFactory() {
builders = new ArrayList<>();
}
@Override
Builder newBuilder() {
WrappedBuilder b = new WrappedBuilder(StatsEvent.newBuilder());
builders.add(b);
return b;
}
}
}