Merge "Fix blockable system notifications" into tm-dev am: ddfeaa18f7
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18292722 Change-Id: I8f405714bc497688d8f214b19c07658ddeff9163 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -320,7 +320,6 @@ package android.app {
|
|||||||
method public void setDemoted(boolean);
|
method public void setDemoted(boolean);
|
||||||
method public void setFgServiceShown(boolean);
|
method public void setFgServiceShown(boolean);
|
||||||
method public void setImportanceLockedByCriticalDeviceFunction(boolean);
|
method public void setImportanceLockedByCriticalDeviceFunction(boolean);
|
||||||
method public void setImportanceLockedByOEM(boolean);
|
|
||||||
method public void setImportantConversation(boolean);
|
method public void setImportantConversation(boolean);
|
||||||
method public void setOriginalImportance(int);
|
method public void setOriginalImportance(int);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ interface INotificationManager
|
|||||||
boolean areNotificationsEnabledForPackage(String pkg, int uid);
|
boolean areNotificationsEnabledForPackage(String pkg, int uid);
|
||||||
boolean areNotificationsEnabled(String pkg);
|
boolean areNotificationsEnabled(String pkg);
|
||||||
int getPackageImportance(String pkg);
|
int getPackageImportance(String pkg);
|
||||||
|
boolean isImportanceLocked(String pkg, int uid);
|
||||||
|
|
||||||
List<String> getAllowedAssistantAdjustments(String pkg);
|
List<String> getAllowedAssistantAdjustments(String pkg);
|
||||||
void allowAssistantAdjustment(String adjustmentType);
|
void allowAssistantAdjustment(String adjustmentType);
|
||||||
|
|||||||
@@ -253,7 +253,6 @@ public final class NotificationChannel implements Parcelable {
|
|||||||
// If this is a blockable system notification channel.
|
// If this is a blockable system notification channel.
|
||||||
private boolean mBlockableSystem = false;
|
private boolean mBlockableSystem = false;
|
||||||
private int mAllowBubbles = DEFAULT_ALLOW_BUBBLE;
|
private int mAllowBubbles = DEFAULT_ALLOW_BUBBLE;
|
||||||
private boolean mImportanceLockedByOEM;
|
|
||||||
private boolean mImportanceLockedDefaultApp;
|
private boolean mImportanceLockedDefaultApp;
|
||||||
private String mParentId = null;
|
private String mParentId = null;
|
||||||
private String mConversationId = null;
|
private String mConversationId = null;
|
||||||
@@ -322,13 +321,13 @@ public final class NotificationChannel implements Parcelable {
|
|||||||
mLightColor = in.readInt();
|
mLightColor = in.readInt();
|
||||||
mBlockableSystem = in.readBoolean();
|
mBlockableSystem = in.readBoolean();
|
||||||
mAllowBubbles = in.readInt();
|
mAllowBubbles = in.readInt();
|
||||||
mImportanceLockedByOEM = in.readBoolean();
|
|
||||||
mOriginalImportance = in.readInt();
|
mOriginalImportance = in.readInt();
|
||||||
mParentId = in.readString();
|
mParentId = in.readString();
|
||||||
mConversationId = in.readString();
|
mConversationId = in.readString();
|
||||||
mDemoted = in.readBoolean();
|
mDemoted = in.readBoolean();
|
||||||
mImportantConvo = in.readBoolean();
|
mImportantConvo = in.readBoolean();
|
||||||
mDeletedTime = in.readLong();
|
mDeletedTime = in.readLong();
|
||||||
|
mImportanceLockedDefaultApp = in.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -382,13 +381,13 @@ public final class NotificationChannel implements Parcelable {
|
|||||||
dest.writeInt(mLightColor);
|
dest.writeInt(mLightColor);
|
||||||
dest.writeBoolean(mBlockableSystem);
|
dest.writeBoolean(mBlockableSystem);
|
||||||
dest.writeInt(mAllowBubbles);
|
dest.writeInt(mAllowBubbles);
|
||||||
dest.writeBoolean(mImportanceLockedByOEM);
|
|
||||||
dest.writeInt(mOriginalImportance);
|
dest.writeInt(mOriginalImportance);
|
||||||
dest.writeString(mParentId);
|
dest.writeString(mParentId);
|
||||||
dest.writeString(mConversationId);
|
dest.writeString(mConversationId);
|
||||||
dest.writeBoolean(mDemoted);
|
dest.writeBoolean(mDemoted);
|
||||||
dest.writeBoolean(mImportantConvo);
|
dest.writeBoolean(mImportantConvo);
|
||||||
dest.writeLong(mDeletedTime);
|
dest.writeLong(mDeletedTime);
|
||||||
|
dest.writeBoolean(mImportanceLockedDefaultApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -847,14 +846,6 @@ public final class NotificationChannel implements Parcelable {
|
|||||||
return mBlockableSystem;
|
return mBlockableSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
@TestApi
|
|
||||||
public void setImportanceLockedByOEM(boolean locked) {
|
|
||||||
mImportanceLockedByOEM = locked;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -1107,8 +1098,8 @@ public final class NotificationChannel implements Parcelable {
|
|||||||
out.attributeBoolean(null, ATT_IMP_CONVERSATION, isImportantConversation());
|
out.attributeBoolean(null, ATT_IMP_CONVERSATION, isImportantConversation());
|
||||||
}
|
}
|
||||||
|
|
||||||
// mImportanceLockedDefaultApp and mImportanceLockedByOEM have a different source of
|
// mImportanceLockedDefaultApp has a different source of truth and so isn't written to
|
||||||
// truth and so aren't written to this xml file
|
// this xml file
|
||||||
|
|
||||||
out.endTag(null, TAG_CHANNEL);
|
out.endTag(null, TAG_CHANNEL);
|
||||||
}
|
}
|
||||||
@@ -1251,7 +1242,6 @@ public final class NotificationChannel implements Parcelable {
|
|||||||
&& Arrays.equals(mVibration, that.mVibration)
|
&& Arrays.equals(mVibration, that.mVibration)
|
||||||
&& Objects.equals(getGroup(), that.getGroup())
|
&& Objects.equals(getGroup(), that.getGroup())
|
||||||
&& Objects.equals(getAudioAttributes(), that.getAudioAttributes())
|
&& Objects.equals(getAudioAttributes(), that.getAudioAttributes())
|
||||||
&& mImportanceLockedByOEM == that.mImportanceLockedByOEM
|
|
||||||
&& mImportanceLockedDefaultApp == that.mImportanceLockedDefaultApp
|
&& mImportanceLockedDefaultApp == that.mImportanceLockedDefaultApp
|
||||||
&& mOriginalImportance == that.mOriginalImportance
|
&& mOriginalImportance == that.mOriginalImportance
|
||||||
&& Objects.equals(getParentChannelId(), that.getParentChannelId())
|
&& Objects.equals(getParentChannelId(), that.getParentChannelId())
|
||||||
@@ -1267,7 +1257,7 @@ public final class NotificationChannel implements Parcelable {
|
|||||||
getUserLockedFields(),
|
getUserLockedFields(),
|
||||||
isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getDeletedTimeMs(),
|
isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getDeletedTimeMs(),
|
||||||
getGroup(), getAudioAttributes(), isBlockable(), mAllowBubbles,
|
getGroup(), getAudioAttributes(), isBlockable(), mAllowBubbles,
|
||||||
mImportanceLockedByOEM, mImportanceLockedDefaultApp, mOriginalImportance,
|
mImportanceLockedDefaultApp, mOriginalImportance,
|
||||||
mParentId, mConversationId, mDemoted, mImportantConvo);
|
mParentId, mConversationId, mDemoted, mImportantConvo);
|
||||||
result = 31 * result + Arrays.hashCode(mVibration);
|
result = 31 * result + Arrays.hashCode(mVibration);
|
||||||
return result;
|
return result;
|
||||||
@@ -1312,7 +1302,6 @@ public final class NotificationChannel implements Parcelable {
|
|||||||
+ ", mAudioAttributes=" + mAudioAttributes
|
+ ", mAudioAttributes=" + mAudioAttributes
|
||||||
+ ", mBlockableSystem=" + mBlockableSystem
|
+ ", mBlockableSystem=" + mBlockableSystem
|
||||||
+ ", mAllowBubbles=" + mAllowBubbles
|
+ ", mAllowBubbles=" + mAllowBubbles
|
||||||
+ ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
|
|
||||||
+ ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp
|
+ ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp
|
||||||
+ ", mOriginalImp=" + mOriginalImportance
|
+ ", mOriginalImp=" + mOriginalImportance
|
||||||
+ ", mParent=" + mParentId
|
+ ", mParent=" + mParentId
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import android.util.IndentingPrintWriter;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.MathUtils;
|
import android.util.MathUtils;
|
||||||
import android.util.Property;
|
import android.util.Property;
|
||||||
|
import android.util.Slog;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
@@ -363,9 +364,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
@Nullable private OnExpansionChangedListener mExpansionChangedListener;
|
@Nullable private OnExpansionChangedListener mExpansionChangedListener;
|
||||||
@Nullable private Runnable mOnIntrinsicHeightReachedRunnable;
|
@Nullable private Runnable mOnIntrinsicHeightReachedRunnable;
|
||||||
|
|
||||||
private SystemNotificationAsyncTask mSystemNotificationAsyncTask =
|
|
||||||
new SystemNotificationAsyncTask();
|
|
||||||
|
|
||||||
private float mTopRoundnessDuringLaunchAnimation;
|
private float mTopRoundnessDuringLaunchAnimation;
|
||||||
private float mBottomRoundnessDuringLaunchAnimation;
|
private float mBottomRoundnessDuringLaunchAnimation;
|
||||||
|
|
||||||
@@ -516,46 +514,21 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
mRowContentBindStage.requestRebind(mEntry, null /* callback */);
|
mRowContentBindStage.requestRebind(mEntry, null /* callback */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Caches whether or not this row contains a system notification. Note, this is only cached
|
|
||||||
* once per notification as the packageInfo can't technically change for a notification row.
|
|
||||||
*/
|
|
||||||
private void cacheIsSystemNotification() {
|
|
||||||
//TODO: This probably shouldn't be in ExpandableNotificationRow
|
|
||||||
if (mEntry != null && mEntry.mIsSystemNotification == null) {
|
|
||||||
if (mSystemNotificationAsyncTask.getStatus() == AsyncTask.Status.PENDING) {
|
|
||||||
// Run async task once, only if it hasn't already been executed. Note this is
|
|
||||||
// executed in serial - no need to parallelize this small task.
|
|
||||||
mSystemNotificationAsyncTask.execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this row is considered non-blockable (i.e. it's a non-blockable system notif
|
* Returns whether this row is considered non-blockable (i.e. it's a non-blockable system notif
|
||||||
* or is in an allowList).
|
* or is in an allowList).
|
||||||
*/
|
*/
|
||||||
public boolean getIsNonblockable() {
|
public boolean getIsNonblockable() {
|
||||||
// If the SystemNotifAsyncTask hasn't finished running or retrieved a value, we'll try once
|
if (mEntry == null || mEntry.getChannel() == null) {
|
||||||
// again, but in-place on the main thread this time. This should rarely ever get called.
|
Log.w(TAG, "missing entry or channel");
|
||||||
if (mEntry != null && mEntry.mIsSystemNotification == null) {
|
return true;
|
||||||
if (DEBUG) {
|
}
|
||||||
Log.d(TAG, "Retrieving isSystemNotification on main thread");
|
if (mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction()
|
||||||
}
|
&& !mEntry.getChannel().isBlockable()) {
|
||||||
mSystemNotificationAsyncTask.cancel(true /* mayInterruptIfRunning */);
|
return true;
|
||||||
mEntry.mIsSystemNotification = isSystemNotification(mContext, mEntry.getSbn());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isNonblockable = mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction();
|
return false;
|
||||||
|
|
||||||
if (!isNonblockable && mEntry != null && mEntry.mIsSystemNotification != null) {
|
|
||||||
if (mEntry.mIsSystemNotification) {
|
|
||||||
if (mEntry.getChannel() != null && !mEntry.getChannel().isBlockable()) {
|
|
||||||
isNonblockable = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isNonblockable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isConversation() {
|
private boolean isConversation() {
|
||||||
@@ -1626,8 +1599,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
mBubblesManagerOptional = bubblesManagerOptional;
|
mBubblesManagerOptional = bubblesManagerOptional;
|
||||||
mNotificationGutsManager = gutsManager;
|
mNotificationGutsManager = gutsManager;
|
||||||
mMetricsLogger = metricsLogger;
|
mMetricsLogger = metricsLogger;
|
||||||
|
|
||||||
cacheIsSystemNotification();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initDimens() {
|
private void initDimens() {
|
||||||
@@ -3545,25 +3516,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Background task for executing IPCs to check if the notification is a system notification. The
|
|
||||||
* output is used for both the blocking helper and the notification info.
|
|
||||||
*/
|
|
||||||
private class SystemNotificationAsyncTask extends AsyncTask<Void, Void, Boolean> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean doInBackground(Void... voids) {
|
|
||||||
return isSystemNotification(mContext, mEntry.getSbn());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Boolean result) {
|
|
||||||
if (mEntry != null) {
|
|
||||||
mEntry.mIsSystemNotification = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setTargetPoint(Point p) {
|
private void setTargetPoint(Point p) {
|
||||||
mTargetPoint = p;
|
mTargetPoint = p;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,10 +322,21 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
|
|||||||
ExpandableNotificationRow row =
|
ExpandableNotificationRow row =
|
||||||
mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
|
mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
|
||||||
row.getEntry().getChannel().setImportanceLockedByCriticalDeviceFunction(true);
|
row.getEntry().getChannel().setImportanceLockedByCriticalDeviceFunction(true);
|
||||||
|
row.getEntry().getChannel().setBlockable(false);
|
||||||
|
|
||||||
assertTrue(row.getIsNonblockable());
|
assertTrue(row.getIsNonblockable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetIsNonblockable_criticalDeviceFunction_butBlockable() throws Exception {
|
||||||
|
ExpandableNotificationRow row =
|
||||||
|
mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
|
||||||
|
row.getEntry().getChannel().setImportanceLockedByCriticalDeviceFunction(true);
|
||||||
|
row.getEntry().getChannel().setBlockable(true);
|
||||||
|
|
||||||
|
assertFalse(row.getIsNonblockable());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCanDismissNoClear() throws Exception {
|
public void testCanDismissNoClear() throws Exception {
|
||||||
ExpandableNotificationRow row =
|
ExpandableNotificationRow row =
|
||||||
|
|||||||
@@ -2284,6 +2284,7 @@ public class NotificationManagerService extends SystemService {
|
|||||||
mNotificationChannelLogger,
|
mNotificationChannelLogger,
|
||||||
mAppOps,
|
mAppOps,
|
||||||
new SysUiStatsEvent.BuilderFactory());
|
new SysUiStatsEvent.BuilderFactory());
|
||||||
|
mPreferencesHelper.updateFixedImportance(mUm.getUsers());
|
||||||
mRankingHelper = new RankingHelper(getContext(),
|
mRankingHelper = new RankingHelper(getContext(),
|
||||||
mRankingHandler,
|
mRankingHandler,
|
||||||
mPreferencesHelper,
|
mPreferencesHelper,
|
||||||
@@ -3631,6 +3632,12 @@ public class NotificationManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isImportanceLocked(String pkg, int uid) {
|
||||||
|
checkCallerIsSystem();
|
||||||
|
return mPreferencesHelper.isImportanceLocked(pkg, uid);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canShowBadge(String pkg, int uid) {
|
public boolean canShowBadge(String pkg, int uid) {
|
||||||
checkCallerIsSystem();
|
checkCallerIsSystem();
|
||||||
|
|||||||
@@ -42,8 +42,10 @@ import android.app.NotificationChannelGroup;
|
|||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ParceledListSlice;
|
import android.content.pm.ParceledListSlice;
|
||||||
|
import android.content.pm.UserInfo;
|
||||||
import android.metrics.LogMaker;
|
import android.metrics.LogMaker;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -146,7 +148,6 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
static final boolean DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS = false;
|
static final boolean DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS = false;
|
||||||
private static final boolean DEFAULT_SHOW_BADGE = true;
|
private static final boolean DEFAULT_SHOW_BADGE = true;
|
||||||
|
|
||||||
private static final boolean DEFAULT_OEM_LOCKED_IMPORTANCE = false;
|
|
||||||
private static final boolean DEFAULT_APP_LOCKED_IMPORTANCE = false;
|
private static final boolean DEFAULT_APP_LOCKED_IMPORTANCE = false;
|
||||||
|
|
||||||
static final boolean DEFAULT_BUBBLES_ENABLED = true;
|
static final boolean DEFAULT_BUBBLES_ENABLED = true;
|
||||||
@@ -193,8 +194,6 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
|
|
||||||
private boolean mAllowInvalidShortcuts = false;
|
private boolean mAllowInvalidShortcuts = false;
|
||||||
|
|
||||||
private Map<String, List<String>> mOemLockedApps = new HashMap();
|
|
||||||
|
|
||||||
public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
|
public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
|
||||||
ZenModeHelper zenHelper, PermissionHelper permHelper,
|
ZenModeHelper zenHelper, PermissionHelper permHelper,
|
||||||
NotificationChannelLogger notificationChannelLogger,
|
NotificationChannelLogger notificationChannelLogger,
|
||||||
@@ -411,7 +410,7 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
channel.populateFromXml(parser);
|
channel.populateFromXml(parser);
|
||||||
}
|
}
|
||||||
channel.setImportanceLockedByCriticalDeviceFunction(
|
channel.setImportanceLockedByCriticalDeviceFunction(
|
||||||
r.defaultAppLockedImportance);
|
r.defaultAppLockedImportance || r.fixedImportance);
|
||||||
|
|
||||||
if (isShortcutOk(channel) && isDeletionOk(channel)) {
|
if (isShortcutOk(channel) && isDeletionOk(channel)) {
|
||||||
r.channels.put(id, channel);
|
r.channels.put(id, channel);
|
||||||
@@ -484,14 +483,6 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
r.visibility = visibility;
|
r.visibility = visibility;
|
||||||
r.showBadge = showBadge;
|
r.showBadge = showBadge;
|
||||||
r.bubblePreference = bubblePreference;
|
r.bubblePreference = bubblePreference;
|
||||||
if (mOemLockedApps.containsKey(r.pkg)) {
|
|
||||||
List<String> channels = mOemLockedApps.get(r.pkg);
|
|
||||||
if (channels == null || channels.isEmpty()) {
|
|
||||||
r.oemLockedImportance = true;
|
|
||||||
} else {
|
|
||||||
r.oemLockedChannels = channels;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
createDefaultChannelIfNeededLocked(r);
|
createDefaultChannelIfNeededLocked(r);
|
||||||
@@ -818,6 +809,13 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isImportanceLocked(String pkg, int uid) {
|
||||||
|
synchronized (mPackagePreferences) {
|
||||||
|
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
|
||||||
|
return r.fixedImportance || r.defaultAppLockedImportance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGroupBlocked(String packageName, int uid, String groupId) {
|
public boolean isGroupBlocked(String packageName, int uid, String groupId) {
|
||||||
if (groupId == null) {
|
if (groupId == null) {
|
||||||
@@ -1008,7 +1006,7 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
clearLockedFieldsLocked(channel);
|
clearLockedFieldsLocked(channel);
|
||||||
|
|
||||||
channel.setImportanceLockedByCriticalDeviceFunction(
|
channel.setImportanceLockedByCriticalDeviceFunction(
|
||||||
r.defaultAppLockedImportance);
|
r.defaultAppLockedImportance || r.fixedImportance);
|
||||||
|
|
||||||
if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
|
if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
|
||||||
channel.setLockscreenVisibility(
|
channel.setLockscreenVisibility(
|
||||||
@@ -1090,8 +1088,7 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
updatedChannel.unlockFields(updatedChannel.getUserLockedFields());
|
updatedChannel.unlockFields(updatedChannel.getUserLockedFields());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mPermissionHelper.isPermissionFixed(r.pkg, UserHandle.getUserId(r.uid))
|
if (channel.isImportanceLockedByCriticalDeviceFunction()
|
||||||
|| channel.isImportanceLockedByCriticalDeviceFunction())
|
|
||||||
&& !(channel.isBlockable() || channel.getImportance() == IMPORTANCE_NONE)) {
|
&& !(channel.isBlockable() || channel.getImportance() == IMPORTANCE_NONE)) {
|
||||||
updatedChannel.setImportance(channel.getImportance());
|
updatedChannel.setImportance(channel.getImportance());
|
||||||
}
|
}
|
||||||
@@ -1267,6 +1264,28 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
mHideSilentStatusBarIcons = hide;
|
mHideSilentStatusBarIcons = hide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateFixedImportance(List<UserInfo> users) {
|
||||||
|
for (UserInfo user : users) {
|
||||||
|
List<PackageInfo> packages = mPm.getInstalledPackagesAsUser(
|
||||||
|
PackageManager.PackageInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY),
|
||||||
|
user.getUserHandle().getIdentifier());
|
||||||
|
for (PackageInfo pi : packages) {
|
||||||
|
boolean fixed = mPermissionHelper.isPermissionFixed(
|
||||||
|
pi.packageName, user.getUserHandle().getIdentifier());
|
||||||
|
if (fixed) {
|
||||||
|
synchronized (mPackagePreferences) {
|
||||||
|
PackagePreferences p = getOrCreatePackagePreferencesLocked(
|
||||||
|
pi.packageName, pi.applicationInfo.uid);
|
||||||
|
p.fixedImportance = true;
|
||||||
|
for (NotificationChannel channel : p.channels.values()) {
|
||||||
|
channel.setImportanceLockedByCriticalDeviceFunction(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void updateDefaultApps(int userId, ArraySet<String> toRemove,
|
public void updateDefaultApps(int userId, ArraySet<String> toRemove,
|
||||||
ArraySet<Pair<String, Integer>> toAdd) {
|
ArraySet<Pair<String, Integer>> toAdd) {
|
||||||
synchronized (mPackagePreferences) {
|
synchronized (mPackagePreferences) {
|
||||||
@@ -1274,8 +1293,10 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
if (userId == UserHandle.getUserId(p.uid)) {
|
if (userId == UserHandle.getUserId(p.uid)) {
|
||||||
if (toRemove != null && toRemove.contains(p.pkg)) {
|
if (toRemove != null && toRemove.contains(p.pkg)) {
|
||||||
p.defaultAppLockedImportance = false;
|
p.defaultAppLockedImportance = false;
|
||||||
for (NotificationChannel channel : p.channels.values()) {
|
if (!p.fixedImportance) {
|
||||||
channel.setImportanceLockedByCriticalDeviceFunction(false);
|
for (NotificationChannel channel : p.channels.values()) {
|
||||||
|
channel.setImportanceLockedByCriticalDeviceFunction(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1934,13 +1955,9 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
pw.print(" defaultAppLocked=");
|
pw.print(" defaultAppLocked=");
|
||||||
pw.print(r.defaultAppLockedImportance);
|
pw.print(r.defaultAppLockedImportance);
|
||||||
}
|
}
|
||||||
if (r.oemLockedImportance != DEFAULT_OEM_LOCKED_IMPORTANCE) {
|
if (r.fixedImportance != DEFAULT_APP_LOCKED_IMPORTANCE) {
|
||||||
pw.print(" oemLocked=");
|
pw.print(" fixedImportance=");
|
||||||
pw.print(r.oemLockedImportance);
|
pw.print(r.fixedImportance);
|
||||||
}
|
|
||||||
if (!r.oemLockedChannels.isEmpty()) {
|
|
||||||
pw.print(" futureLockedChannels=");
|
|
||||||
pw.print(r.oemLockedChannels);
|
|
||||||
}
|
}
|
||||||
pw.println();
|
pw.println();
|
||||||
for (NotificationChannel channel : r.channels.values()) {
|
for (NotificationChannel channel : r.channels.values()) {
|
||||||
@@ -2682,9 +2699,8 @@ public class PreferencesHelper implements RankingConfig {
|
|||||||
int lockedAppFields = DEFAULT_LOCKED_APP_FIELDS;
|
int lockedAppFields = DEFAULT_LOCKED_APP_FIELDS;
|
||||||
// these fields are loaded on boot from a different source of truth and so are not
|
// these fields are loaded on boot from a different source of truth and so are not
|
||||||
// written to notification policy xml
|
// written to notification policy xml
|
||||||
boolean oemLockedImportance = DEFAULT_OEM_LOCKED_IMPORTANCE;
|
|
||||||
List<String> oemLockedChannels = new ArrayList<>();
|
|
||||||
boolean defaultAppLockedImportance = DEFAULT_APP_LOCKED_IMPORTANCE;
|
boolean defaultAppLockedImportance = DEFAULT_APP_LOCKED_IMPORTANCE;
|
||||||
|
boolean fixedImportance = DEFAULT_APP_LOCKED_IMPORTANCE;
|
||||||
|
|
||||||
boolean hasSentInvalidMessage = false;
|
boolean hasSentInvalidMessage = false;
|
||||||
boolean hasSentValidMessage = false;
|
boolean hasSentValidMessage = false;
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.Signature;
|
import android.content.pm.Signature;
|
||||||
|
import android.content.pm.UserInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.media.AudioAttributes;
|
import android.media.AudioAttributes;
|
||||||
@@ -121,6 +122,8 @@ import com.android.os.AtomsProto.PackageNotificationPreferences;
|
|||||||
import com.android.server.UiServiceTestCase;
|
import com.android.server.UiServiceTestCase;
|
||||||
import com.android.server.notification.PermissionHelper.PackagePermission;
|
import com.android.server.notification.PermissionHelper.PackagePermission;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -3523,8 +3526,37 @@ public class PreferencesHelperTest extends UiServiceTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateNotificationChannel_fixedPermission() {
|
public void testUpdateNotificationChannel_fixedPermission() {
|
||||||
|
List<UserInfo> users = ImmutableList.of(new UserInfo(UserHandle.USER_SYSTEM, "user0", 0));
|
||||||
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
|
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
|
||||||
|
PackageInfo pm = new PackageInfo();
|
||||||
|
pm.packageName = PKG_O;
|
||||||
|
pm.applicationInfo = new ApplicationInfo();
|
||||||
|
pm.applicationInfo.uid = UID_O;
|
||||||
|
List<PackageInfo> packages = ImmutableList.of(pm);
|
||||||
|
when(mPm.getInstalledPackagesAsUser(any(), anyInt())).thenReturn(packages);
|
||||||
|
mHelper.updateFixedImportance(users);
|
||||||
|
|
||||||
|
assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
|
||||||
|
|
||||||
|
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
|
||||||
|
mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
|
||||||
|
|
||||||
|
NotificationChannel update = new NotificationChannel("a", "a", IMPORTANCE_NONE);
|
||||||
|
update.setAllowBubbles(false);
|
||||||
|
|
||||||
|
mHelper.updateNotificationChannel(PKG_O, UID_O, update, true);
|
||||||
|
|
||||||
|
assertEquals(IMPORTANCE_HIGH,
|
||||||
|
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).getImportance());
|
||||||
|
assertEquals(false,
|
||||||
|
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateNotificationChannel_defaultApp() {
|
||||||
|
ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
|
||||||
|
toAdd.add(new Pair(PKG_O, UID_O));
|
||||||
|
mHelper.updateDefaultApps(0, null, toAdd);
|
||||||
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
|
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
|
||||||
mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
|
mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
|
||||||
|
|
||||||
@@ -3594,6 +3626,58 @@ public class PreferencesHelperTest extends UiServiceTestCase {
|
|||||||
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
|
mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false).canBubble());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateFixedImportance_multiUser() {
|
||||||
|
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
|
||||||
|
NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
|
||||||
|
NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
|
||||||
|
// different uids, same package
|
||||||
|
mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
|
||||||
|
mHelper.createNotificationChannel(PKG_O, UID_O, b, false, false);
|
||||||
|
mHelper.createNotificationChannel(PKG_O, UserHandle.PER_USER_RANGE + 1, c, true, true);
|
||||||
|
|
||||||
|
UserInfo user = new UserInfo();
|
||||||
|
user.id = 0;
|
||||||
|
List<UserInfo> users = ImmutableList.of(user);
|
||||||
|
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
|
||||||
|
PackageInfo pm = new PackageInfo();
|
||||||
|
pm.packageName = PKG_O;
|
||||||
|
pm.applicationInfo = new ApplicationInfo();
|
||||||
|
pm.applicationInfo.uid = UID_O;
|
||||||
|
List<PackageInfo> packages = ImmutableList.of(pm);
|
||||||
|
when(mPm.getInstalledPackagesAsUser(any(), eq(0))).thenReturn(packages);
|
||||||
|
mHelper.updateFixedImportance(users);
|
||||||
|
|
||||||
|
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
|
||||||
|
.isImportanceLockedByCriticalDeviceFunction());
|
||||||
|
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, b.getId(), false)
|
||||||
|
.isImportanceLockedByCriticalDeviceFunction());
|
||||||
|
assertFalse(mHelper.getNotificationChannel(
|
||||||
|
PKG_O, UserHandle.PER_USER_RANGE + 1, c.getId(), false)
|
||||||
|
.isImportanceLockedByCriticalDeviceFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateFixedImportance_channelDoesNotExistYet() {
|
||||||
|
UserInfo user = new UserInfo();
|
||||||
|
user.id = 0;
|
||||||
|
List<UserInfo> users = ImmutableList.of(user);
|
||||||
|
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
|
||||||
|
PackageInfo pm = new PackageInfo();
|
||||||
|
pm.packageName = PKG_O;
|
||||||
|
pm.applicationInfo = new ApplicationInfo();
|
||||||
|
pm.applicationInfo.uid = UID_O;
|
||||||
|
List<PackageInfo> packages = ImmutableList.of(pm);
|
||||||
|
when(mPm.getInstalledPackagesAsUser(any(), eq(0))).thenReturn(packages);
|
||||||
|
mHelper.updateFixedImportance(users);
|
||||||
|
|
||||||
|
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
|
||||||
|
mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
|
||||||
|
|
||||||
|
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
|
||||||
|
.isImportanceLockedByCriticalDeviceFunction());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateDefaultApps_add_multiUser() {
|
public void testUpdateDefaultApps_add_multiUser() {
|
||||||
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
|
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
|
||||||
@@ -3758,6 +3842,62 @@ public class PreferencesHelperTest extends UiServiceTestCase {
|
|||||||
assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
|
assertTrue(a.isImportanceLockedByCriticalDeviceFunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateFixedImportance_thenDefaultAppsRemoves() {
|
||||||
|
UserInfo user = new UserInfo();
|
||||||
|
user.id = 0;
|
||||||
|
List<UserInfo> users = ImmutableList.of(user);
|
||||||
|
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(true);
|
||||||
|
PackageInfo pm = new PackageInfo();
|
||||||
|
pm.packageName = PKG_O;
|
||||||
|
pm.applicationInfo = new ApplicationInfo();
|
||||||
|
pm.applicationInfo.uid = UID_O;
|
||||||
|
List<PackageInfo> packages = ImmutableList.of(pm);
|
||||||
|
when(mPm.getInstalledPackagesAsUser(any(), eq(0))).thenReturn(packages);
|
||||||
|
mHelper.updateFixedImportance(users);
|
||||||
|
|
||||||
|
ArraySet<String> toRemove = new ArraySet<>();
|
||||||
|
toRemove.add(PKG_O);
|
||||||
|
mHelper.updateDefaultApps(0, toRemove, null);
|
||||||
|
|
||||||
|
assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
|
||||||
|
|
||||||
|
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
|
||||||
|
mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
|
||||||
|
|
||||||
|
// Still locked by permission if not role
|
||||||
|
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
|
||||||
|
.isImportanceLockedByCriticalDeviceFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateDefaultApps_thenNotFixedPermission() {
|
||||||
|
ArraySet<Pair<String, Integer>> toAdd = new ArraySet<>();
|
||||||
|
toAdd.add(new Pair(PKG_O, UID_O));
|
||||||
|
mHelper.updateDefaultApps(0, null, toAdd);
|
||||||
|
|
||||||
|
UserInfo user = new UserInfo();
|
||||||
|
user.id = 0;
|
||||||
|
List<UserInfo> users = ImmutableList.of(user);
|
||||||
|
when(mPermissionHelper.isPermissionFixed(PKG_O, 0)).thenReturn(false);
|
||||||
|
PackageInfo pm = new PackageInfo();
|
||||||
|
pm.packageName = PKG_O;
|
||||||
|
pm.applicationInfo = new ApplicationInfo();
|
||||||
|
pm.applicationInfo.uid = UID_O;
|
||||||
|
List<PackageInfo> packages = ImmutableList.of(pm);
|
||||||
|
when(mPm.getInstalledPackagesAsUser(any(), eq(0))).thenReturn(packages);
|
||||||
|
mHelper.updateFixedImportance(users);
|
||||||
|
|
||||||
|
assertTrue(mHelper.isImportanceLocked(PKG_O, UID_O));
|
||||||
|
|
||||||
|
NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
|
||||||
|
mHelper.createNotificationChannel(PKG_O, UID_O, a, true, false);
|
||||||
|
|
||||||
|
// Still locked by role if not permission
|
||||||
|
assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, a.getId(), false)
|
||||||
|
.isImportanceLockedByCriticalDeviceFunction());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChannelXml_backupDefaultApp() throws Exception {
|
public void testChannelXml_backupDefaultApp() throws Exception {
|
||||||
NotificationChannel channel1 =
|
NotificationChannel channel1 =
|
||||||
|
|||||||
Reference in New Issue
Block a user