Moved notification builder creation to the background
In preparation of future colorization work, the creation
of the notification builder is moved to the background.
Test: manual, add notifications, update them etc.
Test: runtest systemui
Bug: 36561228
Merged-In: Iaec5febf4d8d9da348d77e0d4f6f61b9746fae16
Change-Id: Iaec5febf4d8d9da348d77e0d4f6f61b9746fae16
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
index 2e34f24..3bad5cc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
@@ -18,11 +18,10 @@
import android.app.Notification;
import android.content.Context;
+import android.os.AsyncTask;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
import android.widget.RemoteViews;
import com.android.internal.annotations.VisibleForTesting;
@@ -39,7 +38,8 @@
@VisibleForTesting
static final int FLAG_REINFLATE_ALL = ~0;
private static final int FLAG_REINFLATE_CONTENT_VIEW = 1<<0;
- private static final int FLAG_REINFLATE_EXPANDED_VIEW = 1<<1;
+ @VisibleForTesting
+ static final int FLAG_REINFLATE_EXPANDED_VIEW = 1<<1;
private static final int FLAG_REINFLATE_HEADS_UP_VIEW = 1<<2;
private static final int FLAG_REINFLATE_PUBLIC_VIEW = 1<<3;
private static final int FLAG_REINFLATE_AMBIENT_VIEW = 1<<4;
@@ -50,7 +50,7 @@
private boolean mUsesIncreasedHeadsUpHeight;
private RemoteViews.OnClickHandler mRemoteViewClickHandler;
private boolean mIsChildInGroup;
- private InflationExceptionHandler mInflateExceptionHandler;
+ private InflationCallback mCallback;
private boolean mRedactAmbient;
public NotificationInflater(ExpandableNotificationRow row) {
@@ -66,21 +66,14 @@
*
* @return whether the view was re-inflated
*/
- public boolean setIsChildInGroup(boolean childInGroup) {
+ public void setIsChildInGroup(boolean childInGroup) {
if (childInGroup != mIsChildInGroup) {
mIsChildInGroup = childInGroup;
if (mIsLowPriority) {
- try {
- int flags = FLAG_REINFLATE_CONTENT_VIEW | FLAG_REINFLATE_EXPANDED_VIEW;
- inflateNotificationViews(flags);
- } catch (InflationException e) {
- mInflateExceptionHandler.handleInflationException(
- mRow.getStatusBarNotification(), e);
- }
+ int flags = FLAG_REINFLATE_CONTENT_VIEW | FLAG_REINFLATE_EXPANDED_VIEW;
+ inflateNotificationViews(flags);
}
- return true;
- }
- return false;
+ } ;
}
public void setUsesIncreasedHeight(boolean usesIncreasedHeight) {
@@ -101,39 +94,29 @@
if (mRow.getEntry() == null) {
return;
}
- try {
- inflateNotificationViews(FLAG_REINFLATE_AMBIENT_VIEW);
- } catch (InflationException e) {
- mInflateExceptionHandler.handleInflationException(
- mRow.getStatusBarNotification(), e);
- }
+ inflateNotificationViews(FLAG_REINFLATE_AMBIENT_VIEW);
}
}
- public void inflateNotificationViews() throws InflationException {
+ /**
+ * Inflate all views of this notification on a background thread. This is asynchronous and will
+ * notify the callback once it's finished.
+ */
+ public void inflateNotificationViews() {
inflateNotificationViews(FLAG_REINFLATE_ALL);
}
/**
- * reinflate all views for the specified flags
+ * Reinflate all views for the specified flags on a background thread. This is asynchronous and
+ * will notify the callback once it's finished.
+ *
* @param reInflateFlags flags which views should be reinflated. Use {@link #FLAG_REINFLATE_ALL}
* to reinflate all of views.
- * @throws InflationException
*/
- private void inflateNotificationViews(int reInflateFlags)
- throws InflationException {
+ @VisibleForTesting
+ void inflateNotificationViews(int reInflateFlags) {
StatusBarNotification sbn = mRow.getEntry().notification;
- try {
- final Notification.Builder recoveredBuilder
- = Notification.Builder.recoverBuilder(mRow.getContext(), sbn.getNotification());
- Context packageContext = sbn.getPackageContext(mRow.getContext());
- inflateNotificationViews(reInflateFlags, recoveredBuilder, packageContext);
-
- } catch (RuntimeException e) {
- final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
- Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
- throw new InflationException("Couldn't inflate contentViews");
- }
+ new AsyncInflationTask(mRow.getContext(), sbn, reInflateFlags).execute();
}
@VisibleForTesting
@@ -284,12 +267,13 @@
&& a.getLayoutId() == b.getLayoutId());
}
- public void setInflateExceptionHandler(InflationExceptionHandler inflateExceptionHandler) {
- mInflateExceptionHandler = inflateExceptionHandler;
+ public void setInflationCallback(InflationCallback callback) {
+ mCallback = callback;
}
- public interface InflationExceptionHandler {
+ public interface InflationCallback {
void handleInflationException(StatusBarNotification notification, InflationException e);
+ void onAsyncInflationFinished(NotificationData.Entry entry);
}
public void onDensityOrFontScaleChanged() {
@@ -299,12 +283,67 @@
entry.cachedContentView = null;
entry.cachedHeadsUpContentView = null;
entry.cachedPublicContentView = null;
- try {
- inflateNotificationViews();
- } catch (InflationException e) {
- mInflateExceptionHandler.handleInflationException(
- mRow.getStatusBarNotification(), e);
+ inflateNotificationViews();
+ }
+
+ private class AsyncInflationTask extends AsyncTask<Void, Void, Notification.Builder> {
+
+ private final StatusBarNotification mSbn;
+ private final Context mContext;
+ private final int mReInflateFlags;
+ private Context mPackageContext = null;
+ private Exception mError;
+
+ private AsyncInflationTask(Context context, StatusBarNotification notification,
+ int reInflateFlags) {
+ mSbn = notification;
+ mContext = context;
+ mReInflateFlags = reInflateFlags;
+ mRow.getEntry().addInflationTask(this);
+ }
+
+ @Override
+ protected Notification.Builder doInBackground(Void... params) {
+ try {
+ final Notification.Builder recoveredBuilder
+ = Notification.Builder.recoverBuilder(mContext,
+ mSbn.getNotification());
+ mPackageContext = mSbn.getPackageContext(mContext);
+ return recoveredBuilder;
+ } catch (Exception e) {
+ mError = e;
+ return null;
+ }
+ }
+
+ @Override
+ protected void onPostExecute(Notification.Builder builder) {
+ if (mError == null) {
+ finishInflation(mReInflateFlags, builder, mPackageContext);
+ } else {
+ handleError(mError);
+ }
}
}
+ private void finishInflation(int reinflationFlags, Notification.Builder builder,
+ Context context) {
+ try {
+ inflateNotificationViews(reinflationFlags, builder, context);
+ } catch (RuntimeException e){
+ handleError(e);
+ return;
+ }
+ mRow.onNotificationUpdated();
+ mCallback.onAsyncInflationFinished(mRow.getEntry());
+ }
+
+ private void handleError(Exception e) {
+ StatusBarNotification sbn = mRow.getStatusBarNotification();
+ final String ident = sbn.getPackageName() + "/0x"
+ + Integer.toHexString(sbn.getId());
+ Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
+ mCallback.handleInflationException(sbn,
+ new InflationException("Couldn't inflate contentViews" + e));
+ }
}