Record initial app given importance
To allow users an easy way to 'go back to how it was' (also migrate some tests to other files) Test: atest, cts Bug: 135751328 (cherry picked from commit 03de363ce278b6d708a6d30f83468584a14a65d5) Change-Id: I949f366410d2cb2ab424b1b03222743e6e60d867
This commit is contained in:
@@ -318,10 +318,16 @@ package android.app {
|
||||
}
|
||||
|
||||
public final class NotificationChannel implements android.os.Parcelable {
|
||||
method public int getOriginalImportance();
|
||||
method public boolean isBlockableSystem();
|
||||
method public boolean isImportanceLockedByCriticalDeviceFunction();
|
||||
method public boolean isImportanceLockedByOEM();
|
||||
method public void setBlockableSystem(boolean);
|
||||
method public void setDeleted(boolean);
|
||||
method public void setFgServiceShown(boolean);
|
||||
method public void setImportanceLockedByCriticalDeviceFunction(boolean);
|
||||
method public void setImportanceLockedByOEM(boolean);
|
||||
method public void setOriginalImportance(int);
|
||||
}
|
||||
|
||||
public final class NotificationChannelGroup implements android.os.Parcelable {
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package android.app;
|
||||
|
||||
import static android.app.NotificationManager.IMPORTANCE_HIGH;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
@@ -86,6 +84,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
private static final String ATT_GROUP = "group";
|
||||
private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system";
|
||||
private static final String ATT_ALLOW_BUBBLE = "can_bubble";
|
||||
private static final String ATT_ORIG_IMP = "orig_imp";
|
||||
private static final String DELIMITER = ",";
|
||||
|
||||
/**
|
||||
@@ -151,6 +150,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
private String mName;
|
||||
private String mDesc;
|
||||
private int mImportance = DEFAULT_IMPORTANCE;
|
||||
private int mOriginalImportance = DEFAULT_IMPORTANCE;
|
||||
private boolean mBypassDnd;
|
||||
private int mLockscreenVisibility = DEFAULT_VISIBILITY;
|
||||
private Uri mSound = Settings.System.DEFAULT_NOTIFICATION_URI;
|
||||
@@ -234,6 +234,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
mBlockableSystem = in.readBoolean();
|
||||
mAllowBubbles = in.readBoolean();
|
||||
mImportanceLockedByOEM = in.readBoolean();
|
||||
mOriginalImportance = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -288,6 +289,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
dest.writeBoolean(mBlockableSystem);
|
||||
dest.writeBoolean(mAllowBubbles);
|
||||
dest.writeBoolean(mImportanceLockedByOEM);
|
||||
dest.writeInt(mOriginalImportance);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,6 +309,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void setFgServiceShown(boolean shown) {
|
||||
mFgServiceShown = shown;
|
||||
}
|
||||
@@ -314,6 +317,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void setDeleted(boolean deleted) {
|
||||
mDeleted = deleted;
|
||||
}
|
||||
@@ -322,6 +326,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@TestApi
|
||||
public void setBlockableSystem(boolean blockableSystem) {
|
||||
mBlockableSystem = blockableSystem;
|
||||
}
|
||||
@@ -641,6 +646,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public boolean isBlockableSystem() {
|
||||
return mBlockableSystem;
|
||||
}
|
||||
@@ -677,6 +683,22 @@ public final class NotificationChannel implements Parcelable {
|
||||
return mImportanceLockedDefaultApp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public int getOriginalImportance() {
|
||||
return mOriginalImportance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public void setOriginalImportance(int importance) {
|
||||
mOriginalImportance = importance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the user has chosen the importance of this channel, either to affirm the
|
||||
* initial selection from the app, or changed it to be higher or lower.
|
||||
@@ -729,6 +751,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
setFgServiceShown(safeBool(parser, ATT_FG_SERVICE_SHOWN, false));
|
||||
setBlockableSystem(safeBool(parser, ATT_BLOCKABLE_SYSTEM, false));
|
||||
setAllowBubbles(safeBool(parser, ATT_ALLOW_BUBBLE, DEFAULT_ALLOW_BUBBLE));
|
||||
setOriginalImportance(safeInt(parser, ATT_ORIG_IMP, DEFAULT_IMPORTANCE));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -850,6 +873,9 @@ public final class NotificationChannel implements Parcelable {
|
||||
if (canBubble() != DEFAULT_ALLOW_BUBBLE) {
|
||||
out.attribute(null, ATT_ALLOW_BUBBLE, Boolean.toString(canBubble()));
|
||||
}
|
||||
if (getOriginalImportance() != DEFAULT_IMPORTANCE) {
|
||||
out.attribute(null, ATT_ORIG_IMP, Integer.toString(getOriginalImportance()));
|
||||
}
|
||||
|
||||
// mImportanceLockedDefaultApp and mImportanceLockedByOEM have a different source of
|
||||
// truth and so aren't written to this xml file
|
||||
@@ -896,6 +922,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
record.put(ATT_GROUP, getGroup());
|
||||
record.put(ATT_BLOCKABLE_SYSTEM, isBlockableSystem());
|
||||
record.put(ATT_ALLOW_BUBBLE, canBubble());
|
||||
// TODO: original importance
|
||||
return record;
|
||||
}
|
||||
|
||||
@@ -1005,7 +1032,8 @@ public final class NotificationChannel implements Parcelable {
|
||||
&& Objects.equals(getGroup(), that.getGroup())
|
||||
&& Objects.equals(getAudioAttributes(), that.getAudioAttributes())
|
||||
&& mImportanceLockedByOEM == that.mImportanceLockedByOEM
|
||||
&& mImportanceLockedDefaultApp == that.mImportanceLockedDefaultApp;
|
||||
&& mImportanceLockedDefaultApp == that.mImportanceLockedDefaultApp
|
||||
&& mOriginalImportance == that.mOriginalImportance;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1015,7 +1043,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
getUserLockedFields(),
|
||||
isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(),
|
||||
getAudioAttributes(), isBlockableSystem(), mAllowBubbles,
|
||||
mImportanceLockedByOEM, mImportanceLockedDefaultApp);
|
||||
mImportanceLockedByOEM, mImportanceLockedDefaultApp, mOriginalImportance);
|
||||
result = 31 * result + Arrays.hashCode(mVibration);
|
||||
return result;
|
||||
}
|
||||
@@ -1045,6 +1073,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
+ ", mAllowBubbles=" + mAllowBubbles
|
||||
+ ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
|
||||
+ ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp
|
||||
+ ", mOriginalImp=" + mOriginalImportance
|
||||
+ '}';
|
||||
pw.println(prefix + output);
|
||||
}
|
||||
@@ -1073,6 +1102,7 @@ public final class NotificationChannel implements Parcelable {
|
||||
+ ", mAllowBubbles=" + mAllowBubbles
|
||||
+ ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
|
||||
+ ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp
|
||||
+ ", mOriginalImp=" + mOriginalImportance
|
||||
+ '}';
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.notification;
|
||||
|
||||
import static android.app.NotificationManager.IMPORTANCE_NONE;
|
||||
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
@@ -686,6 +687,11 @@ public class PreferencesHelper implements RankingConfig {
|
||||
}
|
||||
}
|
||||
|
||||
if (existing.getOriginalImportance() == IMPORTANCE_UNSPECIFIED) {
|
||||
existing.setOriginalImportance(channel.getImportance());
|
||||
needsPolicyFileChange = true;
|
||||
}
|
||||
|
||||
updateConfig();
|
||||
return needsPolicyFileChange;
|
||||
}
|
||||
@@ -719,7 +725,7 @@ public class PreferencesHelper implements RankingConfig {
|
||||
if (!r.showBadge) {
|
||||
channel.setShowBadge(false);
|
||||
}
|
||||
|
||||
channel.setOriginalImportance(channel.getImportance());
|
||||
r.channels.put(channel.getId(), channel);
|
||||
if (channel.canBypassDnd() != mAreChannelsBypassingDnd) {
|
||||
updateChannelsBypassingDnd(mContext.getUserId());
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Xml;
|
||||
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.server.UiServiceTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class NotificationChannelTest extends UiServiceTestCase {
|
||||
|
||||
@Test
|
||||
public void testWriteToParcel() {
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel("1", "one", IMPORTANCE_DEFAULT);
|
||||
Parcel parcel = Parcel.obtain();
|
||||
channel.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
NotificationChannel channel1 = NotificationChannel.CREATOR.createFromParcel(parcel);
|
||||
assertEquals(channel, channel1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemBlockable() {
|
||||
NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
|
||||
assertEquals(false, channel.isBlockableSystem());
|
||||
channel.setBlockableSystem(true);
|
||||
assertEquals(true, channel.isBlockableSystem());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyVibration_noException() throws Exception {
|
||||
NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
|
||||
channel.setVibrationPattern(new long[0]);
|
||||
|
||||
XmlSerializer serializer = new FastXmlSerializer();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
|
||||
channel.writeXml(serializer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBackupEmptySound() throws Exception {
|
||||
NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
|
||||
channel.setSound(Uri.EMPTY, null);
|
||||
|
||||
XmlSerializer serializer = new FastXmlSerializer();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
|
||||
channel.writeXmlForBackup(serializer, getContext());
|
||||
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setInput(new BufferedInputStream(
|
||||
new ByteArrayInputStream(baos.toByteArray())), null);
|
||||
NotificationChannel restored = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
|
||||
restored.populateFromXmlForRestore(parser, getContext());
|
||||
|
||||
assertNull(restored.getSound());
|
||||
}
|
||||
}
|
||||
@@ -131,6 +131,7 @@ import android.text.Html;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.Xml;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
@@ -138,6 +139,7 @@ import androidx.test.InstrumentationRegistry;
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
|
||||
import com.android.internal.statusbar.NotificationVisibility;
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.UiServiceTestCase;
|
||||
@@ -156,9 +158,13 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
@@ -3059,6 +3065,25 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(1, mService.countSystemChecks - systemChecks);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBackupEmptySound() throws Exception {
|
||||
NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
|
||||
channel.setSound(Uri.EMPTY, null);
|
||||
|
||||
XmlSerializer serializer = new FastXmlSerializer();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
|
||||
channel.writeXmlForBackup(serializer, getContext());
|
||||
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setInput(new BufferedInputStream(
|
||||
new ByteArrayInputStream(baos.toByteArray())), null);
|
||||
NotificationChannel restored = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
|
||||
restored.populateFromXmlForRestore(parser, getContext());
|
||||
|
||||
assertNull(restored.getSound());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBackup() throws Exception {
|
||||
int systemChecks = mService.countSystemChecks;
|
||||
@@ -3066,6 +3091,17 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
assertEquals(1, mService.countSystemChecks - systemChecks);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyVibration_noException() throws Exception {
|
||||
NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
|
||||
channel.setVibrationPattern(new long[0]);
|
||||
|
||||
XmlSerializer serializer = new FastXmlSerializer();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
|
||||
channel.writeXml(serializer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateUriPermissions_update() throws Exception {
|
||||
NotificationChannel c = new NotificationChannel(
|
||||
|
||||
Reference in New Issue
Block a user