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

Commit 3d5fd7a9 authored by Selim Cinek's avatar Selim Cinek Committed by Android (Google) Code Review
Browse files

Merge "Fixed memory leak with the inflater" into oc-dev

parents 68311f87 67ff2481
Loading
Loading
Loading
Loading
+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) {}
}
+7 −4
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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();
@@ -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() {
@@ -236,7 +239,7 @@ public class NotificationData {
        }
        }


        @VisibleForTesting
        @VisibleForTesting
        public Abortable getRunningTask() {
        public InflationTask getRunningTask() {
            return mRunningTask;
            return mRunningTask;
        }
        }
    }
    }
+24 −5
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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,
@@ -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;
@@ -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();
@@ -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
@@ -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);
+2 −2
Original line number Original line Diff line number Diff line
@@ -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;
+5 −3
Original line number Original line Diff line number Diff line
@@ -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);
        }
        }
    }
    }
@@ -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