Loading packages/SystemUI/src/com/android/systemui/statusbar/InflationTask.java 0 → 100644 +32 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.systemui.statusbar; /** * An interface for running inflation tasks that allows aborting and superseding existing * operations. */ public interface InflationTask { void abort(); /** * Supersedes an existing task. i.e another task was superceeded by this. * * @param task the task that was previously running */ default void supersedeTask(InflationTask task) {} } packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +7 −4 Original line number Original line Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.content.Context; import android.content.Context; import android.graphics.drawable.Icon; import android.graphics.drawable.Icon; import android.os.AsyncTask; import android.os.RemoteException; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemClock; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService; Loading Loading @@ -84,7 +83,7 @@ public class NotificationData { public List<SnoozeCriterion> snoozeCriteria; public List<SnoozeCriterion> snoozeCriteria; private int mCachedContrastColor = COLOR_INVALID; private int mCachedContrastColor = COLOR_INVALID; private int mCachedContrastColorIsFor = COLOR_INVALID; private int mCachedContrastColorIsFor = COLOR_INVALID; private Abortable mRunningTask = null; private InflationTask mRunningTask = null; public Entry(StatusBarNotification n) { public Entry(StatusBarNotification n) { this.key = n.getKey(); this.key = n.getKey(); Loading Loading @@ -225,10 +224,14 @@ public class NotificationData { } } } } public void setInflationTask(Abortable abortableTask) { public void setInflationTask(InflationTask abortableTask) { // abort any existing inflation // abort any existing inflation InflationTask existing = mRunningTask; abortTask(); abortTask(); mRunningTask = abortableTask; mRunningTask = abortableTask; if (existing != null && mRunningTask != null) { mRunningTask.supersedeTask(existing); } } } public void onInflationTaskFinished() { public void onInflationTaskFinished() { Loading @@ -236,7 +239,7 @@ public class NotificationData { } } @VisibleForTesting @VisibleForTesting public Abortable getRunningTask() { public InflationTask getRunningTask() { return mRunningTask; return mRunningTask; } } } } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java +24 −5 Original line number Original line Diff line number Diff line Loading @@ -28,7 +28,7 @@ import android.widget.RemoteViews; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.statusbar.Abortable; import com.android.systemui.statusbar.InflationTask; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationContentView; import com.android.systemui.statusbar.NotificationContentView; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.NotificationData; Loading Loading @@ -130,6 +130,12 @@ public class NotificationInflater { */ */ @VisibleForTesting @VisibleForTesting void inflateNotificationViews(int reInflateFlags) { void inflateNotificationViews(int reInflateFlags) { if (mRow.isRemoved()) { // We don't want to reinflate anything for removed notifications. Otherwise views might // be readded to the stack, leading to leaks. This may happen with low-priority groups // where the removal of already removed children can lead to a reinflation. return; } StatusBarNotification sbn = mRow.getEntry().notification; StatusBarNotification sbn = mRow.getEntry().notification; new AsyncInflationTask(sbn, reInflateFlags, mRow, mIsLowPriority, new AsyncInflationTask(sbn, reInflateFlags, mRow, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient, mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient, Loading Loading @@ -485,17 +491,17 @@ public class NotificationInflater { } } public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress> public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress> implements InflationCallback, Abortable { implements InflationCallback, InflationTask { private final StatusBarNotification mSbn; private final StatusBarNotification mSbn; private final Context mContext; private final Context mContext; private final int mReInflateFlags; private final boolean mIsLowPriority; private final boolean mIsLowPriority; private final boolean mIsChildInGroup; private final boolean mIsChildInGroup; private final boolean mUsesIncreasedHeight; private final boolean mUsesIncreasedHeight; private final InflationCallback mCallback; private final InflationCallback mCallback; private final boolean mUsesIncreasedHeadsUpHeight; private final boolean mUsesIncreasedHeadsUpHeight; private final boolean mRedactAmbient; private final boolean mRedactAmbient; private int mReInflateFlags; private ExpandableNotificationRow mRow; private ExpandableNotificationRow mRow; private Exception mError; private Exception mError; private RemoteViews.OnClickHandler mRemoteViewClickHandler; private RemoteViews.OnClickHandler mRemoteViewClickHandler; Loading @@ -508,8 +514,6 @@ public class NotificationInflater { InflationCallback callback, InflationCallback callback, RemoteViews.OnClickHandler remoteViewClickHandler) { RemoteViews.OnClickHandler remoteViewClickHandler) { mRow = row; mRow = row; NotificationData.Entry entry = row.getEntry(); entry.setInflationTask(this); mSbn = notification; mSbn = notification; mReInflateFlags = reInflateFlags; mReInflateFlags = reInflateFlags; mContext = mRow.getContext(); mContext = mRow.getContext(); Loading @@ -520,6 +524,13 @@ public class NotificationInflater { mRedactAmbient = redactAmbient; mRedactAmbient = redactAmbient; mRemoteViewClickHandler = remoteViewClickHandler; mRemoteViewClickHandler = remoteViewClickHandler; mCallback = callback; mCallback = callback; NotificationData.Entry entry = row.getEntry(); entry.setInflationTask(this); } @VisibleForTesting public int getReInflateFlags() { return mReInflateFlags; } } @Override @Override Loading Loading @@ -579,6 +590,14 @@ public class NotificationInflater { } } } } @Override public void supersedeTask(InflationTask task) { if (task instanceof AsyncInflationTask) { // We want to inflate all flags of the previous task as well mReInflateFlags |= ((AsyncInflationTask) task).mReInflateFlags; } } @Override @Override public void handleInflationException(StatusBarNotification notification, Exception e) { public void handleInflationException(StatusBarNotification notification, Exception e) { handleError(e); handleError(e); Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/RowInflaterTask.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -22,14 +22,14 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.statusbar.Abortable; import com.android.systemui.statusbar.InflationTask; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.NotificationData; /** /** * An inflater task that asynchronously inflates a ExpandableNotificationRow * An inflater task that asynchronously inflates a ExpandableNotificationRow */ */ public class RowInflaterTask implements Abortable, AsyncLayoutInflater.OnInflateFinishedListener { public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInflateFinishedListener { private RowInflationFinishedListener mListener; private RowInflationFinishedListener mListener; private NotificationData.Entry mEntry; private NotificationData.Entry mEntry; private boolean mCancelled; private boolean mCancelled; Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +5 −3 Original line number Original line Diff line number Diff line Loading @@ -1612,7 +1612,9 @@ public class StatusBar extends SystemUI implements DemoMode, @Override @Override public void onAsyncInflationFinished(Entry entry) { public void onAsyncInflationFinished(Entry entry) { mPendingNotifications.remove(entry.key); mPendingNotifications.remove(entry.key); if (mNotificationData.get(entry.key) == null) { // If there was an async task started after the removal, we don't want to add it back to // the list, otherwise we might get leaks. if (mNotificationData.get(entry.key) == null && !entry.row.isRemoved()) { addEntry(entry); addEntry(entry); } } } } Loading Loading @@ -1762,10 +1764,10 @@ public class StatusBar extends SystemUI implements DemoMode, continue; continue; } } toRemove.add(row); toRemove.add(row); toRemove.get(i).setKeepInParent(true); row.setKeepInParent(true); // we need to set this state earlier as otherwise we might generate some weird // we need to set this state earlier as otherwise we might generate some weird // animations // animations toRemove.get(i).setRemoved(); row.setRemoved(); } } } } } } Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/InflationTask.java 0 → 100644 +32 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.systemui.statusbar; /** * An interface for running inflation tasks that allows aborting and superseding existing * operations. */ public interface InflationTask { void abort(); /** * Supersedes an existing task. i.e another task was superceeded by this. * * @param task the task that was previously running */ default void supersedeTask(InflationTask task) {} }
packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +7 −4 Original line number Original line Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.content.Context; import android.content.Context; import android.graphics.drawable.Icon; import android.graphics.drawable.Icon; import android.os.AsyncTask; import android.os.RemoteException; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemClock; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService; Loading Loading @@ -84,7 +83,7 @@ public class NotificationData { public List<SnoozeCriterion> snoozeCriteria; public List<SnoozeCriterion> snoozeCriteria; private int mCachedContrastColor = COLOR_INVALID; private int mCachedContrastColor = COLOR_INVALID; private int mCachedContrastColorIsFor = COLOR_INVALID; private int mCachedContrastColorIsFor = COLOR_INVALID; private Abortable mRunningTask = null; private InflationTask mRunningTask = null; public Entry(StatusBarNotification n) { public Entry(StatusBarNotification n) { this.key = n.getKey(); this.key = n.getKey(); Loading Loading @@ -225,10 +224,14 @@ public class NotificationData { } } } } public void setInflationTask(Abortable abortableTask) { public void setInflationTask(InflationTask abortableTask) { // abort any existing inflation // abort any existing inflation InflationTask existing = mRunningTask; abortTask(); abortTask(); mRunningTask = abortableTask; mRunningTask = abortableTask; if (existing != null && mRunningTask != null) { mRunningTask.supersedeTask(existing); } } } public void onInflationTaskFinished() { public void onInflationTaskFinished() { Loading @@ -236,7 +239,7 @@ public class NotificationData { } } @VisibleForTesting @VisibleForTesting public Abortable getRunningTask() { public InflationTask getRunningTask() { return mRunningTask; return mRunningTask; } } } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java +24 −5 Original line number Original line Diff line number Diff line Loading @@ -28,7 +28,7 @@ import android.widget.RemoteViews; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.statusbar.Abortable; import com.android.systemui.statusbar.InflationTask; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationContentView; import com.android.systemui.statusbar.NotificationContentView; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.NotificationData; Loading Loading @@ -130,6 +130,12 @@ public class NotificationInflater { */ */ @VisibleForTesting @VisibleForTesting void inflateNotificationViews(int reInflateFlags) { void inflateNotificationViews(int reInflateFlags) { if (mRow.isRemoved()) { // We don't want to reinflate anything for removed notifications. Otherwise views might // be readded to the stack, leading to leaks. This may happen with low-priority groups // where the removal of already removed children can lead to a reinflation. return; } StatusBarNotification sbn = mRow.getEntry().notification; StatusBarNotification sbn = mRow.getEntry().notification; new AsyncInflationTask(sbn, reInflateFlags, mRow, mIsLowPriority, new AsyncInflationTask(sbn, reInflateFlags, mRow, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient, mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient, Loading Loading @@ -485,17 +491,17 @@ public class NotificationInflater { } } public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress> public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress> implements InflationCallback, Abortable { implements InflationCallback, InflationTask { private final StatusBarNotification mSbn; private final StatusBarNotification mSbn; private final Context mContext; private final Context mContext; private final int mReInflateFlags; private final boolean mIsLowPriority; private final boolean mIsLowPriority; private final boolean mIsChildInGroup; private final boolean mIsChildInGroup; private final boolean mUsesIncreasedHeight; private final boolean mUsesIncreasedHeight; private final InflationCallback mCallback; private final InflationCallback mCallback; private final boolean mUsesIncreasedHeadsUpHeight; private final boolean mUsesIncreasedHeadsUpHeight; private final boolean mRedactAmbient; private final boolean mRedactAmbient; private int mReInflateFlags; private ExpandableNotificationRow mRow; private ExpandableNotificationRow mRow; private Exception mError; private Exception mError; private RemoteViews.OnClickHandler mRemoteViewClickHandler; private RemoteViews.OnClickHandler mRemoteViewClickHandler; Loading @@ -508,8 +514,6 @@ public class NotificationInflater { InflationCallback callback, InflationCallback callback, RemoteViews.OnClickHandler remoteViewClickHandler) { RemoteViews.OnClickHandler remoteViewClickHandler) { mRow = row; mRow = row; NotificationData.Entry entry = row.getEntry(); entry.setInflationTask(this); mSbn = notification; mSbn = notification; mReInflateFlags = reInflateFlags; mReInflateFlags = reInflateFlags; mContext = mRow.getContext(); mContext = mRow.getContext(); Loading @@ -520,6 +524,13 @@ public class NotificationInflater { mRedactAmbient = redactAmbient; mRedactAmbient = redactAmbient; mRemoteViewClickHandler = remoteViewClickHandler; mRemoteViewClickHandler = remoteViewClickHandler; mCallback = callback; mCallback = callback; NotificationData.Entry entry = row.getEntry(); entry.setInflationTask(this); } @VisibleForTesting public int getReInflateFlags() { return mReInflateFlags; } } @Override @Override Loading Loading @@ -579,6 +590,14 @@ public class NotificationInflater { } } } } @Override public void supersedeTask(InflationTask task) { if (task instanceof AsyncInflationTask) { // We want to inflate all flags of the previous task as well mReInflateFlags |= ((AsyncInflationTask) task).mReInflateFlags; } } @Override @Override public void handleInflationException(StatusBarNotification notification, Exception e) { public void handleInflationException(StatusBarNotification notification, Exception e) { handleError(e); handleError(e); Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/RowInflaterTask.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -22,14 +22,14 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup; import com.android.systemui.R; import com.android.systemui.R; import com.android.systemui.statusbar.Abortable; import com.android.systemui.statusbar.InflationTask; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.NotificationData; /** /** * An inflater task that asynchronously inflates a ExpandableNotificationRow * An inflater task that asynchronously inflates a ExpandableNotificationRow */ */ public class RowInflaterTask implements Abortable, AsyncLayoutInflater.OnInflateFinishedListener { public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInflateFinishedListener { private RowInflationFinishedListener mListener; private RowInflationFinishedListener mListener; private NotificationData.Entry mEntry; private NotificationData.Entry mEntry; private boolean mCancelled; private boolean mCancelled; Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +5 −3 Original line number Original line Diff line number Diff line Loading @@ -1612,7 +1612,9 @@ public class StatusBar extends SystemUI implements DemoMode, @Override @Override public void onAsyncInflationFinished(Entry entry) { public void onAsyncInflationFinished(Entry entry) { mPendingNotifications.remove(entry.key); mPendingNotifications.remove(entry.key); if (mNotificationData.get(entry.key) == null) { // If there was an async task started after the removal, we don't want to add it back to // the list, otherwise we might get leaks. if (mNotificationData.get(entry.key) == null && !entry.row.isRemoved()) { addEntry(entry); addEntry(entry); } } } } Loading Loading @@ -1762,10 +1764,10 @@ public class StatusBar extends SystemUI implements DemoMode, continue; continue; } } toRemove.add(row); toRemove.add(row); toRemove.get(i).setKeepInParent(true); row.setKeepInParent(true); // we need to set this state earlier as otherwise we might generate some weird // we need to set this state earlier as otherwise we might generate some weird // animations // animations toRemove.get(i).setRemoved(); row.setRemoved(); } } } } } } Loading