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

Commit bf7133e3 authored by Jeff DeCew's avatar Jeff DeCew Committed by Matías Hernández
Browse files

Crash when using the insecure constructor of ExpandableNotificationRow

Bug: 333550910
Test: atest SystemUITests
Flag: NONE
Change-Id: Ia58fea516d845a82cfa406ba732561ebb2902613
parent 5492bfb1
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1767,7 +1767,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
     */
    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
        this(context, attrs, context);
        Log.e(TAG, "This constructor shouldn't be called");
        // NOTE(b/317503801): Always crash when using the insecure constructor.
        throw new UnsupportedOperationException("Insecure constructor");
    }

    /**
+18 −4
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ import com.android.systemui.statusbar.InflationTask;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.util.time.SystemClock;

import java.util.concurrent.Executor;

import javax.inject.Inject;

/**
@@ -58,10 +60,22 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf
    }

    /**
     * Inflates a new notificationView. This should not be called twice on this object
     * Inflates a new notificationView asynchronously, calling the {@code listener} on the main
     * thread when done. This should not be called twice on this object.
     */
    public void inflate(Context context, ViewGroup parent, NotificationEntry entry,
            RowInflationFinishedListener listener) {
        inflate(context, parent, entry, null, listener);
    }

    /**
     * Inflates a new notificationView asynchronously, calling the {@code listener} on the supplied
     * {@code listenerExecutor} (or the main thread if null) when done. This should not be called
     * twice on this object.
     */
    @VisibleForTesting
    public void inflate(Context context, ViewGroup parent, NotificationEntry entry,
            @Nullable Executor listenerExecutor, RowInflationFinishedListener listener) {
        if (TRACE_ORIGIN) {
            mInflateOrigin = new Throwable("inflate requested here");
        }
@@ -72,7 +86,7 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf

        mLogger.logInflateStart(entry);
        mInflateStartTimeMs = mSystemClock.elapsedRealtime();
        inflater.inflate(R.layout.status_bar_notification_row, parent, this);
        inflater.inflate(R.layout.status_bar_notification_row, parent, listenerExecutor, this);
    }

    private RowAsyncLayoutInflater makeRowInflater(NotificationEntry entry) {
@@ -80,12 +94,12 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf
    }

    @VisibleForTesting
    static class RowAsyncLayoutInflater implements AsyncLayoutFactory {
    public static class RowAsyncLayoutInflater implements AsyncLayoutFactory {
        private final NotificationEntry mEntry;
        private final SystemClock mSystemClock;
        private final RowInflaterTaskLogger mLogger;

        RowAsyncLayoutInflater(NotificationEntry entry, SystemClock systemClock,
        public RowAsyncLayoutInflater(NotificationEntry entry, SystemClock systemClock,
                RowInflaterTaskLogger logger) {
            mEntry = entry;
            mSystemClock = systemClock;
+12 −4
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.RowContentBindParams;
import com.android.systemui.statusbar.notification.row.RowContentBindStage;
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
import com.android.systemui.statusbar.notification.row.RowInflaterTaskLogger;
import com.android.systemui.util.time.FakeSystemClock;

import org.junit.Before;
import org.junit.Test;
@@ -114,20 +117,25 @@ public class DynamicChildBindControllerTest extends SysuiTestCase {

    private NotificationEntry addGroup(int size) {
        NotificationEntry summary = new NotificationEntryBuilder().build();
        summary.setRow(createRow());
        summary.setRow(createRow(summary));
        ArrayList<NotificationEntry> children = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            NotificationEntry child = new NotificationEntryBuilder().build();
            child.setRow(createRow());
            child.setRow(createRow(child));
            children.add(child);
        }
        mGroupNotifs.put(summary, children);
        return summary;
    }

    private ExpandableNotificationRow createRow() {
    private ExpandableNotificationRow createRow(NotificationEntry entry) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        inflater.setFactory2(
                new RowInflaterTask.RowAsyncLayoutInflater(entry, new FakeSystemClock(), mock(
                        RowInflaterTaskLogger.class)));

        ExpandableNotificationRow row = (ExpandableNotificationRow)
                LayoutInflater.from(mContext).inflate(R.layout.status_bar_notification_row, null);
                inflater.inflate(R.layout.status_bar_notification_row, null);
        row.getPrivateLayout().setContractedChild(new View(mContext));
        row.getPrivateLayout().setExpandedChild(new View(mContext));
        return row;
+3 −2
Original line number Diff line number Diff line
@@ -79,10 +79,11 @@ class NotificationContentViewTest : SysuiTestCase() {
        initMocks(this)
        fakeParent =
            spy(FrameLayout(mContext, /* attrs= */ null).also { it.visibility = View.GONE })
        val mockEntry = createMockNotificationEntry()
        row =
            spy(
                ExpandableNotificationRow(mContext, /* attrs= */ null).apply {
                    entry = createMockNotificationEntry()
                ExpandableNotificationRow(mContext, /* attrs= */ null, mockEntry).apply {
                    entry = mockEntry
                }
            )
        ViewUtils.attachView(fakeParent)
+8 −1
Original line number Diff line number Diff line
package com.android.systemui.statusbar.notification.stack

import android.service.notification.StatusBarNotification
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.LayoutInflater
@@ -14,6 +15,7 @@ import com.android.systemui.res.R
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator
import com.android.systemui.statusbar.NotificationShelf
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor
@@ -457,8 +459,13 @@ open class NotificationShelfTest : SysuiTestCase() {
        expansionFraction: Float,
        expectedAlpha: Float
    ) {
        val sbnMock: StatusBarNotification = mock()
        val mockEntry = mock<NotificationEntry>().apply {
            whenever(this.sbn).thenReturn(sbnMock)
        }
        val row = ExpandableNotificationRow(mContext, null, mockEntry)
        whenever(ambientState.lastVisibleBackgroundChild)
            .thenReturn(ExpandableNotificationRow(mContext, null))
            .thenReturn(row)
        whenever(ambientState.isExpansionChanging).thenReturn(true)
        whenever(ambientState.expansionFraction).thenReturn(expansionFraction)
        whenever(hostLayoutController.speedBumpIndex).thenReturn(0)