mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-08-31 06:31:55 +00:00
176 lines
8.1 KiB
Diff
176 lines
8.1 KiB
Diff
![]() |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Valentin Iftime <valiiftime@google.com>
|
||
|
Date: Wed, 22 Feb 2023 09:38:55 +0100
|
||
|
Subject: [PATCH] Prevent RemoteViews crashing SystemUi
|
||
|
|
||
|
Catch canvas drawing exceptions caused by unsuported image sizes.
|
||
|
|
||
|
Test: 1. Post a custom view notification with a layout
|
||
|
containing an ImageView that references a 5k x 5k image
|
||
|
2. Add an App Widget to the home screen with that has the
|
||
|
layout mentioned above as preview/initial layout.
|
||
|
|
||
|
Bug: 268193777
|
||
|
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:cfc0b34432ab54e3fa472db5c43e620293f64a5d)
|
||
|
Merged-In: Ib3bda769c499b4069b49c566b1b227f98f707a8a
|
||
|
Change-Id: Ib3bda769c499b4069b49c566b1b227f98f707a8a
|
||
|
---
|
||
|
.../android/appwidget/AppWidgetHostView.java | 39 ++++++++++++++-----
|
||
|
.../row/ExpandableNotificationRow.java | 1 +
|
||
|
.../row/NotificationContentView.java | 37 ++++++++++++++++++
|
||
|
3 files changed, 67 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
|
||
|
index 85f0e2342412..eafb631216e5 100644
|
||
|
--- a/core/java/android/appwidget/AppWidgetHostView.java
|
||
|
+++ b/core/java/android/appwidget/AppWidgetHostView.java
|
||
|
@@ -28,6 +28,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.Rect;
|
||
|
import android.os.Bundle;
|
||
|
@@ -250,19 +251,26 @@ 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
|
||
|
@@ -711,4 +719,15 @@ public class AppWidgetHostView extends FrameLayout {
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
+
|
||
|
+ @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);
|
||
|
+ 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 12d537d3c646..37f780290935 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
|
||
|
@@ -69,6 +69,7 @@ import android.widget.RemoteViews;
|
||
|
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.systemui.Dependency;
|
||
|
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 0c5b27b92878..e05269ebf6b4 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
|
||
|
@@ -20,8 +20,10 @@ 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.os.Build;
|
||
|
+import android.os.RemoteException;
|
||
|
import android.service.notification.StatusBarNotification;
|
||
|
import android.util.ArrayMap;
|
||
|
import android.util.ArraySet;
|
||
|
@@ -39,6 +41,7 @@ import android.widget.LinearLayout;
|
||
|
import com.android.internal.annotations.VisibleForTesting;
|
||
|
import com.android.internal.util.ContrastColorUtil;
|
||
|
import com.android.systemui.Dependency;
|
||
|
+import com.android.internal.statusbar.IStatusBarService;
|
||
|
import com.android.systemui.R;
|
||
|
import com.android.systemui.statusbar.MediaTransferManager;
|
||
|
import com.android.systemui.statusbar.RemoteInputController;
|
||
|
@@ -111,6 +114,8 @@ public class NotificationContentView extends FrameLayout {
|
||
|
private NotificationGroupManager mGroupManager;
|
||
|
private RemoteInputController mRemoteInputController;
|
||
|
private Runnable mExpandedVisibleListener;
|
||
|
+ private IStatusBarService mStatusBarService;
|
||
|
+
|
||
|
/**
|
||
|
* List of listeners for when content views become inactive (i.e. not the showing view).
|
||
|
*/
|
||
|
@@ -167,6 +172,7 @@ public class NotificationContentView extends FrameLayout {
|
||
|
mMediaTransferManager = new MediaTransferManager(getContext());
|
||
|
mSmartReplyConstants = Dependency.get(SmartReplyConstants.class);
|
||
|
mSmartReplyController = Dependency.get(SmartReplyController.class);
|
||
|
+ mStatusBarService = Dependency.get(IStatusBarService.class);
|
||
|
initView();
|
||
|
}
|
||
|
|
||
|
@@ -1818,4 +1824,35 @@ public class NotificationContentView extends FrameLayout {
|
||
|
public RemoteInputView getExpandedRemoteInput() {
|
||
|
return mExpandedRemoteInput;
|
||
|
}
|
||
|
+
|
||
|
+ @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);
|
||
|
+ if (mStatusBarService != null) {
|
||
|
+ // report notification inflation errors back up
|
||
|
+ // to notification delegates
|
||
|
+ mStatusBarService.onNotificationError(
|
||
|
+ mStatusBarNotification.getPackageName(),
|
||
|
+ mStatusBarNotification.getTag(),
|
||
|
+ mStatusBarNotification.getId(),
|
||
|
+ mStatusBarNotification.getUid(),
|
||
|
+ mStatusBarNotification.getInitialPid(),
|
||
|
+ exception.getMessage(),
|
||
|
+ mStatusBarNotification.getUser().getIdentifier());
|
||
|
+ }
|
||
|
+ } catch (RemoteException ex) {
|
||
|
+ Log.e(TAG, "cancelNotification failed: " + ex);
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|