Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 756a475b authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Fix blockable system notifications

Notifications can be non-blockable if their app has the
permission fixed or if the app holds certain roles.

Calculate that on device boot and role change, and use the same
source of truth for all UIs. As a bonus, we can remove some
systemui binder calls.

Test: SystemUiTests & FrameworkUiServicesTests
TesT: verify that 'usb debugging connected' notifs are non blockable
but magnification ones are, in systemui and settings
Fixes: 231662091

Change-Id: I980718ab61196901d976f9ea8ee035eafc021fc8
parent 7e6088fa
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -320,7 +320,6 @@ package android.app {
    method public void setDemoted(boolean);
    method public void setFgServiceShown(boolean);
    method public void setImportanceLockedByCriticalDeviceFunction(boolean);
    method public void setImportanceLockedByOEM(boolean);
    method public void setImportantConversation(boolean);
    method public void setOriginalImportance(int);
  }
+1 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ interface INotificationManager
    boolean areNotificationsEnabledForPackage(String pkg, int uid);
    boolean areNotificationsEnabled(String pkg);
    int getPackageImportance(String pkg);
    boolean isImportanceLocked(String pkg, int uid);

    List<String> getAllowedAssistantAdjustments(String pkg);
    void allowAssistantAdjustment(String adjustmentType);
+5 −16
Original line number Diff line number Diff line
@@ -253,7 +253,6 @@ public final class NotificationChannel implements Parcelable {
    // If this is a blockable system notification channel.
    private boolean mBlockableSystem = false;
    private int mAllowBubbles = DEFAULT_ALLOW_BUBBLE;
    private boolean mImportanceLockedByOEM;
    private boolean mImportanceLockedDefaultApp;
    private String mParentId = null;
    private String mConversationId = null;
@@ -322,13 +321,13 @@ public final class NotificationChannel implements Parcelable {
        mLightColor = in.readInt();
        mBlockableSystem = in.readBoolean();
        mAllowBubbles = in.readInt();
        mImportanceLockedByOEM = in.readBoolean();
        mOriginalImportance = in.readInt();
        mParentId = in.readString();
        mConversationId = in.readString();
        mDemoted = in.readBoolean();
        mImportantConvo = in.readBoolean();
        mDeletedTime = in.readLong();
        mImportanceLockedDefaultApp = in.readBoolean();
    }

    @Override
@@ -382,13 +381,13 @@ public final class NotificationChannel implements Parcelable {
        dest.writeInt(mLightColor);
        dest.writeBoolean(mBlockableSystem);
        dest.writeInt(mAllowBubbles);
        dest.writeBoolean(mImportanceLockedByOEM);
        dest.writeInt(mOriginalImportance);
        dest.writeString(mParentId);
        dest.writeString(mConversationId);
        dest.writeBoolean(mDemoted);
        dest.writeBoolean(mImportantConvo);
        dest.writeLong(mDeletedTime);
        dest.writeBoolean(mImportanceLockedDefaultApp);
    }

    /**
@@ -847,14 +846,6 @@ public final class NotificationChannel implements Parcelable {
        return mBlockableSystem;
    }

    /**
     * @hide
     */
    @TestApi
    public void setImportanceLockedByOEM(boolean locked) {
        mImportanceLockedByOEM = locked;
    }

    /**
     * @hide
     */
@@ -1107,8 +1098,8 @@ public final class NotificationChannel implements Parcelable {
            out.attributeBoolean(null, ATT_IMP_CONVERSATION, isImportantConversation());
        }

        // mImportanceLockedDefaultApp and mImportanceLockedByOEM have a different source of
        // truth and so aren't written to this xml file
        // mImportanceLockedDefaultApp has a different source of truth and so isn't written to
        // this xml file

        out.endTag(null, TAG_CHANNEL);
    }
@@ -1251,7 +1242,6 @@ public final class NotificationChannel implements Parcelable {
                && Arrays.equals(mVibration, that.mVibration)
                && Objects.equals(getGroup(), that.getGroup())
                && Objects.equals(getAudioAttributes(), that.getAudioAttributes())
                && mImportanceLockedByOEM == that.mImportanceLockedByOEM
                && mImportanceLockedDefaultApp == that.mImportanceLockedDefaultApp
                && mOriginalImportance == that.mOriginalImportance
                && Objects.equals(getParentChannelId(), that.getParentChannelId())
@@ -1267,7 +1257,7 @@ public final class NotificationChannel implements Parcelable {
                getUserLockedFields(),
                isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getDeletedTimeMs(),
                getGroup(), getAudioAttributes(), isBlockable(), mAllowBubbles,
                mImportanceLockedByOEM, mImportanceLockedDefaultApp, mOriginalImportance,
                mImportanceLockedDefaultApp, mOriginalImportance,
                mParentId, mConversationId, mDemoted, mImportantConvo);
        result = 31 * result + Arrays.hashCode(mVibration);
        return result;
@@ -1312,7 +1302,6 @@ public final class NotificationChannel implements Parcelable {
                + ", mAudioAttributes=" + mAudioAttributes
                + ", mBlockableSystem=" + mBlockableSystem
                + ", mAllowBubbles=" + mAllowBubbles
                + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
                + ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp
                + ", mOriginalImp=" + mOriginalImportance
                + ", mParent=" + mParentId
+9 −57
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
import android.util.Property;
import android.util.Slog;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -363,9 +364,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    @Nullable private OnExpansionChangedListener mExpansionChangedListener;
    @Nullable private Runnable mOnIntrinsicHeightReachedRunnable;

    private SystemNotificationAsyncTask mSystemNotificationAsyncTask =
            new SystemNotificationAsyncTask();

    private float mTopRoundnessDuringLaunchAnimation;
    private float mBottomRoundnessDuringLaunchAnimation;

@@ -516,46 +514,21 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        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
     * or is in an allowList).
     */
    public boolean getIsNonblockable() {
        // If the SystemNotifAsyncTask hasn't finished running or retrieved a value, we'll try once
        // again, but in-place on the main thread this time. This should rarely ever get called.
        if (mEntry != null && mEntry.mIsSystemNotification == null) {
            if (DEBUG) {
                Log.d(TAG, "Retrieving isSystemNotification on main thread");
        if (mEntry == null || mEntry.getChannel() == null) {
            Log.w(TAG, "missing entry or channel");
            return true;
        }
            mSystemNotificationAsyncTask.cancel(true /* mayInterruptIfRunning */);
            mEntry.mIsSystemNotification = isSystemNotification(mContext, mEntry.getSbn());
        if (mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction()
                && !mEntry.getChannel().isBlockable()) {
            return true;
        }

        boolean isNonblockable = mEntry.getChannel().isImportanceLockedByCriticalDeviceFunction();

        if (!isNonblockable && mEntry != null && mEntry.mIsSystemNotification != null) {
            if (mEntry.mIsSystemNotification) {
                if (mEntry.getChannel() != null && !mEntry.getChannel().isBlockable()) {
                    isNonblockable = true;
                }
            }
        }
        return isNonblockable;
        return false;
    }

    private boolean isConversation() {
@@ -1626,8 +1599,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        mBubblesManagerOptional = bubblesManagerOptional;
        mNotificationGutsManager = gutsManager;
        mMetricsLogger = metricsLogger;

        cacheIsSystemNotification();
    }

    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) {
        mTargetPoint = p;
    }
+11 −0
Original line number Diff line number Diff line
@@ -322,10 +322,21 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
        ExpandableNotificationRow row =
                mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
        row.getEntry().getChannel().setImportanceLockedByCriticalDeviceFunction(true);
        row.getEntry().getChannel().setBlockable(false);

        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
    public void testCanDismissNoClear() throws Exception {
        ExpandableNotificationRow row =
Loading