summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Valentin Iftime <valiiftime@google.com> 2023-03-22 19:23:10 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2023-03-22 19:23:10 +0000
commita452c1c95540f03ba7eb961a9a42028085463694 (patch)
treee71efc98c1bd80f089bedf5a8d5d1621b4139c65
parentfa2f72a22da2ffaf118014536d97a3e487e22d2c (diff)
parent10752edb540a053e304139894f941fcaef60949b (diff)
[DO NOT MERGE] Prevent RemoteViews crashing SystemUi am: 10752edb54
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22071923 Change-Id: Ia822486ac562d9c87b8762313e55373de96a5282 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java54
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java4
6 files changed, 99 insertions, 18 deletions
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 8be2b4873c67..b0ffd7690377 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -31,6 +31,7 @@ import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
+import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -312,20 +313,27 @@ public class AppWidgetHostView extends FrameLayout {
super.onLayout(changed, left, top, right, bottom);
} catch (final RuntimeException e) {
Log.e(TAG, "Remote provider threw runtime exception, using error view instead.", e);
- removeViewInLayout(mView);
- View child = getErrorView();
- prepareView(child);
- addViewInLayout(child, 0, child.getLayoutParams());
- measureChild(child, MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
- child.layout(0, 0, child.getMeasuredWidth() + mPaddingLeft + mPaddingRight,
- child.getMeasuredHeight() + mPaddingTop + mPaddingBottom);
- mView = child;
- mViewMode = VIEW_MODE_ERROR;
+ handleViewError();
}
}
/**
+ * Remove bad view and replace with error message view
+ */
+ private void handleViewError() {
+ removeViewInLayout(mView);
+ View child = getErrorView();
+ prepareView(child);
+ addViewInLayout(child, 0, child.getLayoutParams());
+ measureChild(child, MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
+ child.layout(0, 0, child.getMeasuredWidth() + mPaddingLeft + mPaddingRight,
+ child.getMeasuredHeight() + mPaddingTop + mPaddingBottom);
+ mView = child;
+ mViewMode = VIEW_MODE_ERROR;
+ }
+
+ /**
* Provide guidance about the size of this widget to the AppWidgetManager. The widths and
* heights should correspond to the full area the AppWidgetHostView is given. Padding added by
* the framework will be accounted for automatically. This information gets embedded into the
@@ -940,4 +948,15 @@ public class AppWidgetHostView extends FrameLayout {
reapplyLastRemoteViews();
}
}
+
+ @Override
+ protected void dispatchDraw(@NonNull Canvas canvas) {
+ try {
+ super.dispatchDraw(canvas);
+ } catch (Exception e) {
+ // Catch draw exceptions that may be caused by RemoteViews
+ Log.e(TAG, "Drawing view failed: " + e);
+ post(this::handleViewError);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index eb496abad460..84c8f1c934b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -72,6 +72,7 @@ import android.widget.ImageView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ContrastColorUtil;
import com.android.internal.widget.CachingIconView;
import com.android.internal.widget.CallLayout;
@@ -1551,7 +1552,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
NotificationGutsManager gutsManager,
MetricsLogger metricsLogger,
SmartReplyConstants smartReplyConstants,
- SmartReplyController smartReplyController) {
+ SmartReplyController smartReplyController,
+ IStatusBarService statusBarService) {
mEntry = entry;
mAppName = appName;
if (mMenuRow == null) {
@@ -1580,7 +1582,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mPeopleNotificationIdentifier,
rivSubcomponentFactory,
smartReplyConstants,
- smartReplyController);
+ smartReplyController,
+ statusBarService);
}
mOnUserInteractionCallback = onUserInteractionCallback;
mBubblesManagerOptional = bubblesManagerOptional;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 599039d46556..2d8f2ca98031 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -28,6 +28,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
@@ -100,8 +101,8 @@ public class ExpandableNotificationRowController implements NotifViewController
private final Optional<BubblesManager> mBubblesManagerOptional;
private final SmartReplyConstants mSmartReplyConstants;
private final SmartReplyController mSmartReplyController;
-
private final ExpandableNotificationRowDragController mDragController;
+ private final IStatusBarService mStatusBarService;
@Inject
public ExpandableNotificationRowController(
@@ -133,7 +134,8 @@ public class ExpandableNotificationRowController implements NotifViewController
FeatureFlags featureFlags,
PeopleNotificationIdentifier peopleNotificationIdentifier,
Optional<BubblesManager> bubblesManagerOptional,
- ExpandableNotificationRowDragController dragController) {
+ ExpandableNotificationRowDragController dragController,
+ IStatusBarService statusBarService) {
mView = view;
mListContainer = listContainer;
mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory;
@@ -164,6 +166,7 @@ public class ExpandableNotificationRowController implements NotifViewController
mMetricsLogger = metricsLogger;
mSmartReplyConstants = smartReplyConstants;
mSmartReplyController = smartReplyController;
+ mStatusBarService = statusBarService;
}
/**
@@ -194,7 +197,8 @@ public class ExpandableNotificationRowController implements NotifViewController
mNotificationGutsManager,
mMetricsLogger,
mSmartReplyConstants,
- mSmartReplyController
+ mSmartReplyController,
+ mStatusBarService
);
mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
if (mAllowLongPress) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index ba26cfaa30b4..f647365755bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -21,10 +21,13 @@ import android.annotation.Nullable;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
+import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.os.RemoteException;
import android.provider.Settings;
+import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.IndentingPrintWriter;
@@ -39,6 +42,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.RemoteInputController;
@@ -129,6 +133,7 @@ public class NotificationContentView extends FrameLayout implements Notification
private Runnable mExpandedVisibleListener;
private PeopleNotificationIdentifier mPeopleIdentifier;
private RemoteInputViewSubcomponent.Factory mRemoteInputSubcomponentFactory;
+ private IStatusBarService mStatusBarService;
/**
* List of listeners for when content views become inactive (i.e. not the showing view).
@@ -194,11 +199,13 @@ public class NotificationContentView extends FrameLayout implements Notification
PeopleNotificationIdentifier peopleNotificationIdentifier,
RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
SmartReplyConstants smartReplyConstants,
- SmartReplyController smartReplyController) {
+ SmartReplyController smartReplyController,
+ IStatusBarService statusBarService) {
mPeopleIdentifier = peopleNotificationIdentifier;
mRemoteInputSubcomponentFactory = rivSubcomponentFactory;
mSmartReplyConstants = smartReplyConstants;
mSmartReplyController = smartReplyController;
+ mStatusBarService = statusBarService;
}
public void reinflate() {
@@ -2090,4 +2097,49 @@ public class NotificationContentView extends FrameLayout implements Notification
@Nullable RemoteInputView mView;
@Nullable RemoteInputViewController mController;
}
+
+ @VisibleForTesting
+ protected void setContractedWrapper(NotificationViewWrapper contractedWrapper) {
+ mContractedWrapper = contractedWrapper;
+ }
+ @VisibleForTesting
+ protected void setExpandedWrapper(NotificationViewWrapper expandedWrapper) {
+ mExpandedWrapper = expandedWrapper;
+ }
+ @VisibleForTesting
+ protected void setHeadsUpWrapper(NotificationViewWrapper headsUpWrapper) {
+ mHeadsUpWrapper = headsUpWrapper;
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ try {
+ super.dispatchDraw(canvas);
+ } catch (Exception e) {
+ // Catch draw exceptions that may be caused by RemoteViews
+ Log.e(TAG, "Drawing view failed: " + e);
+ cancelNotification(e);
+ }
+ }
+
+ private void cancelNotification(Exception exception) {
+ try {
+ setVisibility(GONE);
+ final StatusBarNotification sbn = mNotificationEntry.getSbn();
+ if (mStatusBarService != null) {
+ // report notification inflation errors back up
+ // to notification delegates
+ mStatusBarService.onNotificationError(
+ sbn.getPackageName(),
+ sbn.getTag(),
+ sbn.getId(),
+ sbn.getUid(),
+ sbn.getInitialPid(),
+ exception.getMessage(),
+ sbn.getUser().getIdentifier());
+ }
+ } catch (RemoteException ex) {
+ Log.e(TAG, "cancelNotification failed: " + ex);
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
index 251ac7d250fe..2d9397e2dd7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
@@ -281,7 +281,8 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
mock(FeatureFlags.class),
mPeopleNotificationIdentifier,
Optional.of(mock(BubblesManager.class)),
- mock(ExpandableNotificationRowDragController.class)));
+ mock(ExpandableNotificationRowDragController.class),
+ mock(IStatusBarService.class)));
when(mNotificationRowComponentBuilder.activatableNotificationView(any()))
.thenReturn(mNotificationRowComponentBuilder);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 38bd078589dc..49d1c5d86a16 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -48,6 +48,7 @@ import android.view.LayoutInflater;
import android.widget.RemoteViews;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.TestableDependency;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
@@ -523,7 +524,8 @@ public class NotificationTestHelper {
mock(NotificationGutsManager.class),
mock(MetricsLogger.class),
mock(SmartReplyConstants.class),
- mock(SmartReplyController.class));
+ mock(SmartReplyController.class),
+ mock(IStatusBarService.class));
row.setAboveShelfChangedListener(aboveShelf -> { });
mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags);