NotificationInflater.java revision 5fb73f86299d9cc616ca741f8c7c4af2485cc273
11a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek/*
21a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * Copyright (C) 2017 The Android Open Source Project
31a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek *
41a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * Licensed under the Apache License, Version 2.0 (the "License");
51a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * you may not use this file except in compliance with the License.
61a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * You may obtain a copy of the License at
71a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek *
81a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek *      http://www.apache.org/licenses/LICENSE-2.0
91a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek *
101a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * Unless required by applicable law or agreed to in writing, software
111a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * distributed under the License is distributed on an "AS IS" BASIS,
121a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * See the License for the specific language governing permissions and
141a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * limitations under the License
151a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek */
161a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
171a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekpackage com.android.systemui.statusbar.notification;
181a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
191a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.app.Notification;
201a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.content.Context;
212630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinekimport android.os.AsyncTask;
221a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.service.notification.StatusBarNotification;
231a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.util.Log;
241a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.view.View;
251a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.widget.RemoteViews;
261a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinekimport com.android.internal.annotations.VisibleForTesting;
281a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.ExpandableNotificationRow;
291a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.NotificationContentView;
301a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.NotificationData;
311a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.phone.StatusBar;
321a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
331a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek/**
341a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * A utility that inflates the right kind of contentView based on the state
351a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek */
361a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekpublic class NotificationInflater {
371a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
3810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    @VisibleForTesting
3910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    static final int FLAG_REINFLATE_ALL = ~0;
40c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_CONTENT_VIEW = 1<<0;
412630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    @VisibleForTesting
422630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    static final int FLAG_REINFLATE_EXPANDED_VIEW = 1<<1;
43c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_HEADS_UP_VIEW = 1<<2;
44c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_PUBLIC_VIEW = 1<<3;
45c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_AMBIENT_VIEW = 1<<4;
46c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
471a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private final ExpandableNotificationRow mRow;
481a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private boolean mIsLowPriority;
491a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private boolean mUsesIncreasedHeight;
501a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private boolean mUsesIncreasedHeadsUpHeight;
511a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private RemoteViews.OnClickHandler mRemoteViewClickHandler;
52c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private boolean mIsChildInGroup;
532630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    private InflationCallback mCallback;
541a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos    private boolean mRedactAmbient;
551a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
561a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public NotificationInflater(ExpandableNotificationRow row) {
571a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mRow = row;
581a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
591a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
601a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setIsLowPriority(boolean isLowPriority) {
611a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mIsLowPriority = isLowPriority;
621a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
631a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
64c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    /**
65c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * Set whether the notification is a child in a group
66c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     *
67c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * @return whether the view was re-inflated
68c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     */
692630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    public void setIsChildInGroup(boolean childInGroup) {
70c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        if (childInGroup != mIsChildInGroup) {
71c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            mIsChildInGroup = childInGroup;
72c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            if (mIsLowPriority) {
732630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                int flags = FLAG_REINFLATE_CONTENT_VIEW | FLAG_REINFLATE_EXPANDED_VIEW;
742630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                inflateNotificationViews(flags);
75c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            }
762630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        } ;
77c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
78c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
791a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setUsesIncreasedHeight(boolean usesIncreasedHeight) {
801a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mUsesIncreasedHeight = usesIncreasedHeight;
811a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
821a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
831a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setUsesIncreasedHeadsUpHeight(boolean usesIncreasedHeight) {
841a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mUsesIncreasedHeadsUpHeight = usesIncreasedHeight;
851a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
861a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
871a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setRemoteViewClickHandler(RemoteViews.OnClickHandler remoteViewClickHandler) {
881a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mRemoteViewClickHandler = remoteViewClickHandler;
891a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
901a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
911a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos    public void setRedactAmbient(boolean redactAmbient) {
921a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos        if (mRedactAmbient != redactAmbient) {
931a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            mRedactAmbient = redactAmbient;
941a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            if (mRow.getEntry() == null) {
951a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                return;
961a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            }
972630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            inflateNotificationViews(FLAG_REINFLATE_AMBIENT_VIEW);
981a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos        }
991a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos    }
1001a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos
1012630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    /**
1022630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek     * Inflate all views of this notification on a background thread. This is asynchronous and will
1032630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek     * notify the callback once it's finished.
1042630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek     */
1052630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    public void inflateNotificationViews() {
106c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        inflateNotificationViews(FLAG_REINFLATE_ALL);
107c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
108c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
109c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    /**
1102630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek     * Reinflate all views for the specified flags on a background thread. This is asynchronous and
1112630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek     * will notify the callback once it's finished.
1122630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek     *
113c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * @param reInflateFlags flags which views should be reinflated. Use {@link #FLAG_REINFLATE_ALL}
114c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     *                       to reinflate all of views.
115c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     */
1162630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    @VisibleForTesting
1172630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    void inflateNotificationViews(int reInflateFlags) {
11810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        StatusBarNotification sbn = mRow.getEntry().notification;
1192630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        new AsyncInflationTask(mRow.getContext(), sbn, reInflateFlags).execute();
12010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    }
1211a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
12210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    @VisibleForTesting
12310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    void inflateNotificationViews(int reInflateFlags,
12410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            Notification.Builder builder, Context packageContext) {
12510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        NotificationData.Entry entry = mRow.getEntry();
12610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        NotificationContentView privateLayout = mRow.getPrivateLayout();
1271a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos        NotificationContentView publicLayout = mRow.getPublicLayout();
1281a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos
12910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        boolean isLowPriority = mIsLowPriority && !mIsChildInGroup;
13010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
13110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newContentView = createContentView(builder,
13210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    isLowPriority, mUsesIncreasedHeight);
13310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (!compareRemoteViews(newContentView,
13410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    entry.cachedContentView)) {
13510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                View contentViewLocal = newContentView.apply(
13610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        packageContext,
13710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        privateLayout,
13810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
13910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                contentViewLocal.setIsRootNamespace(true);
14010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setContractedChild(contentViewLocal);
14110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else {
14210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                newContentView.reapply(packageContext,
14310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        privateLayout.getContractedChild(),
14410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
145c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            }
14610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedContentView = newContentView;
14710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
148c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
14910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
15010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newBigContentView = createBigContentView(
15110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    builder, isLowPriority);
15210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (newBigContentView != null) {
15310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                if (!compareRemoteViews(newBigContentView, entry.cachedBigContentView)) {
15410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    View bigContentViewLocal = newBigContentView.apply(
15510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            packageContext,
15610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            privateLayout,
1571a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
15810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    bigContentViewLocal.setIsRootNamespace(true);
15910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    privateLayout.setExpandedChild(bigContentViewLocal);
1601a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                } else {
16110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    newBigContentView.reapply(packageContext,
16210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            privateLayout.getExpandedChild(),
1631a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
1641a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                }
16510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else if (entry.cachedBigContentView != null) {
16610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setExpandedChild(null);
1671a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            }
16810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedBigContentView = newBigContentView;
16910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            mRow.setExpandable(newBigContentView != null);
17010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
1711a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
17210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
17310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newHeadsUpContentView =
17410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    builder.createHeadsUpContentView(mUsesIncreasedHeadsUpHeight);
17510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (newHeadsUpContentView != null) {
17610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                if (!compareRemoteViews(newHeadsUpContentView,
17710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        entry.cachedHeadsUpContentView)) {
17810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    View headsUpContentViewLocal = newHeadsUpContentView.apply(
17910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            packageContext,
1801a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            privateLayout,
1811a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
18210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    headsUpContentViewLocal.setIsRootNamespace(true);
18310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    privateLayout.setHeadsUpChild(headsUpContentViewLocal);
1841a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                } else {
18510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    newHeadsUpContentView.reapply(packageContext,
18610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            privateLayout.getHeadsUpChild(),
1871a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
1881a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                }
18910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else if (entry.cachedHeadsUpContentView != null) {
19010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setHeadsUpChild(null);
1911a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            }
19210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedHeadsUpContentView = newHeadsUpContentView;
19310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
1941a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
19510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
19610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newPublicNotification
19710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    = builder.makePublicContentView();
19810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) {
19910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                View publicContentView = newPublicNotification.apply(
20010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        packageContext,
20110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        publicLayout,
20210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
20310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                publicContentView.setIsRootNamespace(true);
20410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                publicLayout.setContractedChild(publicContentView);
20510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else {
20610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                newPublicNotification.reapply(packageContext,
20710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        publicLayout.getContractedChild(),
20810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
20910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            }
21010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedPublicContentView = newPublicNotification;
21110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
21210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek
21310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
2141a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            final RemoteViews newAmbientNotification = mRedactAmbient
2151a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                    ? builder.makePublicAmbientNotification()
2161a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                    : builder.makeAmbientNotification();
2171a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            NotificationContentView newParent = mRedactAmbient ? publicLayout : privateLayout;
2181a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            NotificationContentView otherParent = !mRedactAmbient ? publicLayout : privateLayout;
2191a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos
2201a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            if (newParent.getAmbientChild() == null ||
2211a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                    !compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) {
22210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                View ambientContentView = newAmbientNotification.apply(
22310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        packageContext,
2241a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                        newParent,
22510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
22610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                ambientContentView.setIsRootNamespace(true);
2271a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                newParent.setAmbientChild(ambientContentView);
2281a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                otherParent.setAmbientChild(null);
22910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else {
23010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                newAmbientNotification.reapply(packageContext,
2311a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                        newParent.getAmbientChild(),
23210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
23310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            }
23410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedAmbientContentView = newAmbientNotification;
2351a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2361a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2371a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2381a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private RemoteViews createBigContentView(Notification.Builder builder,
2391a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            boolean isLowPriority) {
2401a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        RemoteViews bigContentView = builder.createBigContentView();
2411a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        if (bigContentView != null) {
2421a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            return bigContentView;
2431a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2441a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        if (isLowPriority) {
2451a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            RemoteViews contentView = builder.createContentView();
2461a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            Notification.Builder.makeHeaderExpanded(contentView);
2471a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            return contentView;
2481a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2491a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        return null;
2501a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2511a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2521a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private RemoteViews createContentView(Notification.Builder builder,
2531a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            boolean isLowPriority, boolean useLarge) {
2541a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        if (isLowPriority) {
2551a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            return builder.makeLowPriorityContentView(false /* useRegularSubtext */);
2561a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2571a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        return builder.createContentView(useLarge);
2581a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2591a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2601a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    // Returns true if the RemoteViews are the same.
2611a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private boolean compareRemoteViews(final RemoteViews a, final RemoteViews b) {
2621a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        return (a == null && b == null) ||
2631a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                (a != null && b != null
2641a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && b.getPackage() != null
2651a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && a.getPackage() != null
2661a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && a.getPackage().equals(b.getPackage())
2671a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && a.getLayoutId() == b.getLayoutId());
2681a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
269c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
2702630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    public void setInflationCallback(InflationCallback callback) {
2712630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        mCallback = callback;
272c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
273c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
2742630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    public interface InflationCallback {
275c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        void handleInflationException(StatusBarNotification notification, InflationException e);
2762630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        void onAsyncInflationFinished(NotificationData.Entry entry);
277c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
27810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek
2791a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void onDensityOrFontScaleChanged() {
2801a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        NotificationData.Entry entry = mRow.getEntry();
2811a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedAmbientContentView = null;
2821a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedBigContentView = null;
2831a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedContentView = null;
2841a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedHeadsUpContentView = null;
2851a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedPublicContentView = null;
2862630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        inflateNotificationViews();
2872630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    }
2882630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek
2892630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    private class AsyncInflationTask extends AsyncTask<Void, Void, Notification.Builder> {
2902630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek
2912630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        private final StatusBarNotification mSbn;
2922630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        private final Context mContext;
2932630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        private final int mReInflateFlags;
2942630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        private Context mPackageContext = null;
2952630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        private Exception mError;
2962630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek
2972630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        private AsyncInflationTask(Context context, StatusBarNotification notification,
2982630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                int reInflateFlags) {
2992630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            mSbn = notification;
3002630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            mContext = context;
3012630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            mReInflateFlags = reInflateFlags;
3022630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            mRow.getEntry().addInflationTask(this);
3032630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        }
3042630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek
3052630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        @Override
3062630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        protected Notification.Builder doInBackground(Void... params) {
3072630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            try {
3082630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                final Notification.Builder recoveredBuilder
3092630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                        = Notification.Builder.recoverBuilder(mContext,
3102630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                        mSbn.getNotification());
3112630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                mPackageContext = mSbn.getPackageContext(mContext);
3125fb73f86299d9cc616ca741f8c7c4af2485cc273Selim Cinek                Notification notification = mSbn.getNotification();
3135fb73f86299d9cc616ca741f8c7c4af2485cc273Selim Cinek                if (notification.isColorizedMedia()) {
3145fb73f86299d9cc616ca741f8c7c4af2485cc273Selim Cinek                    MediaNotificationProcessor processor = new MediaNotificationProcessor(
3155fb73f86299d9cc616ca741f8c7c4af2485cc273Selim Cinek                            mPackageContext);
3165fb73f86299d9cc616ca741f8c7c4af2485cc273Selim Cinek                    processor.processNotification(notification, recoveredBuilder);
3175fb73f86299d9cc616ca741f8c7c4af2485cc273Selim Cinek                }
3182630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                return recoveredBuilder;
3192630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            } catch (Exception e) {
3202630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                mError = e;
3212630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                return null;
3222630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            }
3232630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        }
3242630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek
3252630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        @Override
3262630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        protected void onPostExecute(Notification.Builder builder) {
3272630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            if (mError == null) {
3282630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                finishInflation(mReInflateFlags, builder, mPackageContext);
3292630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            } else {
3302630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                handleError(mError);
3312630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            }
3322630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        }
3332630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    }
3342630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek
3352630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    private void finishInflation(int reinflationFlags, Notification.Builder builder,
3362630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            Context context) {
3371a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        try {
3382630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            inflateNotificationViews(reinflationFlags, builder, context);
3392630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        } catch (RuntimeException e){
3402630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            handleError(e);
3412630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek            return;
3421a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
3432630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        mRow.onNotificationUpdated();
3442630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        mCallback.onAsyncInflationFinished(mRow.getEntry());
3451a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
3461a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
3472630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    private void handleError(Exception e) {
3482630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        StatusBarNotification sbn = mRow.getStatusBarNotification();
3492630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        final String ident = sbn.getPackageName() + "/0x"
3502630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                + Integer.toHexString(sbn.getId());
3512630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
3522630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek        mCallback.handleInflationException(sbn,
3532630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek                new InflationException("Couldn't inflate contentViews" + e));
3542630dc7ecf16a965321cfc615104f372cd2b0e96Selim Cinek    }
3551a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek}
356