NotificationInflater.java revision 10790672a98debafb8882971e94ff26aec9a6bfa
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;
211a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.service.notification.StatusBarNotification;
221a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.util.Log;
231a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.view.View;
241a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.widget.RemoteViews;
251a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinekimport com.android.internal.annotations.VisibleForTesting;
271a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.ExpandableNotificationRow;
281a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.NotificationContentView;
291a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.NotificationData;
301a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.phone.StatusBar;
311a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
321a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek/**
331a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * A utility that inflates the right kind of contentView based on the state
341a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek */
351a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekpublic class NotificationInflater {
361a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
3710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    @VisibleForTesting
3810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    static final int FLAG_REINFLATE_ALL = ~0;
39c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_CONTENT_VIEW = 1<<0;
40c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_EXPANDED_VIEW = 1<<1;
41c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_HEADS_UP_VIEW = 1<<2;
42c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_PUBLIC_VIEW = 1<<3;
43c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_AMBIENT_VIEW = 1<<4;
44c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
451a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private final ExpandableNotificationRow mRow;
461a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private boolean mIsLowPriority;
471a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private boolean mUsesIncreasedHeight;
481a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private boolean mUsesIncreasedHeadsUpHeight;
491a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private RemoteViews.OnClickHandler mRemoteViewClickHandler;
50c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private boolean mIsChildInGroup;
51c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private InflationExceptionHandler mInflateExceptionHandler;
521a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
531a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public NotificationInflater(ExpandableNotificationRow row) {
541a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mRow = row;
551a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
561a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
571a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setIsLowPriority(boolean isLowPriority) {
581a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mIsLowPriority = isLowPriority;
591a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
601a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
61c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    /**
62c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * Set whether the notification is a child in a group
63c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     *
64c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * @return whether the view was re-inflated
65c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     */
66c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    public boolean setIsChildInGroup(boolean childInGroup) {
67c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        if (childInGroup != mIsChildInGroup) {
68c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            mIsChildInGroup = childInGroup;
69c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            if (mIsLowPriority) {
70c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                try {
71c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                    int flags = FLAG_REINFLATE_CONTENT_VIEW | FLAG_REINFLATE_EXPANDED_VIEW;
72c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                    inflateNotificationViews(flags);
73c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                } catch (InflationException e) {
74c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                    mInflateExceptionHandler.handleInflationException(
75c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                            mRow.getStatusBarNotification(), e);
76c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                }
77c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            }
78c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            return true;
79c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        }
80c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        return false;
81c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
82c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
831a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setUsesIncreasedHeight(boolean usesIncreasedHeight) {
841a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mUsesIncreasedHeight = usesIncreasedHeight;
851a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
861a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
871a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setUsesIncreasedHeadsUpHeight(boolean usesIncreasedHeight) {
881a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mUsesIncreasedHeadsUpHeight = usesIncreasedHeight;
891a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
901a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
911a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setRemoteViewClickHandler(RemoteViews.OnClickHandler remoteViewClickHandler) {
921a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mRemoteViewClickHandler = remoteViewClickHandler;
931a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
941a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
951a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void inflateNotificationViews() throws InflationException {
96c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        inflateNotificationViews(FLAG_REINFLATE_ALL);
97c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
98c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
99c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    /**
100c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * reinflate all views for the specified flags
101c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * @param reInflateFlags flags which views should be reinflated. Use {@link #FLAG_REINFLATE_ALL}
102c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     *                       to reinflate all of views.
103c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * @throws InflationException
104c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     */
105c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private void inflateNotificationViews(int reInflateFlags)
106c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            throws InflationException {
10710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        StatusBarNotification sbn = mRow.getEntry().notification;
1081a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        try {
1091a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            final Notification.Builder recoveredBuilder
11010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    = Notification.Builder.recoverBuilder(mRow.getContext(), sbn.getNotification());
11110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            Context packageContext = sbn.getPackageContext(mRow.getContext());
11210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            inflateNotificationViews(reInflateFlags, recoveredBuilder, packageContext);
1131a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
11410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        } catch (RuntimeException e) {
11510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
11610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
11710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            throw new InflationException("Couldn't inflate contentViews");
11810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
11910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    }
1201a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
12110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    @VisibleForTesting
12210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    void inflateNotificationViews(int reInflateFlags,
12310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            Notification.Builder builder, Context packageContext) {
12410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        NotificationData.Entry entry = mRow.getEntry();
12510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        NotificationContentView privateLayout = mRow.getPrivateLayout();
12610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        boolean isLowPriority = mIsLowPriority && !mIsChildInGroup;
12710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
12810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newContentView = createContentView(builder,
12910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    isLowPriority, mUsesIncreasedHeight);
13010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (!compareRemoteViews(newContentView,
13110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    entry.cachedContentView)) {
13210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                View contentViewLocal = newContentView.apply(
13310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        packageContext,
13410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        privateLayout,
13510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
13610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                contentViewLocal.setIsRootNamespace(true);
13710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setContractedChild(contentViewLocal);
13810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else {
13910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                newContentView.reapply(packageContext,
14010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        privateLayout.getContractedChild(),
14110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
142c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            }
14310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedContentView = newContentView;
14410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
145c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
14610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
14710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newBigContentView = createBigContentView(
14810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    builder, isLowPriority);
14910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (newBigContentView != null) {
15010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                if (!compareRemoteViews(newBigContentView, entry.cachedBigContentView)) {
15110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    View bigContentViewLocal = newBigContentView.apply(
15210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            packageContext,
15310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            privateLayout,
1541a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
15510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    bigContentViewLocal.setIsRootNamespace(true);
15610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    privateLayout.setExpandedChild(bigContentViewLocal);
1571a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                } else {
15810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    newBigContentView.reapply(packageContext,
15910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            privateLayout.getExpandedChild(),
1601a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
1611a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                }
16210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else if (entry.cachedBigContentView != null) {
16310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setExpandedChild(null);
1641a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            }
16510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedBigContentView = newBigContentView;
16610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            mRow.setExpandable(newBigContentView != null);
16710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
1681a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
16910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
17010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newHeadsUpContentView =
17110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    builder.createHeadsUpContentView(mUsesIncreasedHeadsUpHeight);
17210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (newHeadsUpContentView != null) {
17310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                if (!compareRemoteViews(newHeadsUpContentView,
17410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        entry.cachedHeadsUpContentView)) {
17510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    View headsUpContentViewLocal = newHeadsUpContentView.apply(
17610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            packageContext,
1771a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            privateLayout,
1781a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
17910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    headsUpContentViewLocal.setIsRootNamespace(true);
18010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    privateLayout.setHeadsUpChild(headsUpContentViewLocal);
1811a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                } else {
18210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    newHeadsUpContentView.reapply(packageContext,
18310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            privateLayout.getHeadsUpChild(),
1841a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
1851a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                }
18610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else if (entry.cachedHeadsUpContentView != null) {
18710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setHeadsUpChild(null);
1881a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            }
18910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedHeadsUpContentView = newHeadsUpContentView;
19010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
1911a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
19210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
19310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            NotificationContentView publicLayout = mRow.getPublicLayout();
19410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newPublicNotification
19510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    = builder.makePublicContentView();
19610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) {
19710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                View publicContentView = newPublicNotification.apply(
19810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        packageContext,
19910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        publicLayout,
20010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
20110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                publicContentView.setIsRootNamespace(true);
20210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                publicLayout.setContractedChild(publicContentView);
20310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else {
20410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                newPublicNotification.reapply(packageContext,
20510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        publicLayout.getContractedChild(),
20610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
20710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            }
20810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedPublicContentView = newPublicNotification;
20910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
21010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek
21110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
21210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newAmbientNotification
21310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    = builder.makeAmbientNotification();
21410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (!compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) {
21510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                View ambientContentView = newAmbientNotification.apply(
21610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        packageContext,
21710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        privateLayout,
21810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
21910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                ambientContentView.setIsRootNamespace(true);
22010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setAmbientChild(ambientContentView);
22110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else {
22210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                newAmbientNotification.reapply(packageContext,
22310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        privateLayout.getAmbientChild(),
22410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
22510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            }
22610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedAmbientContentView = newAmbientNotification;
2271a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2281a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2291a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2301a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private RemoteViews createBigContentView(Notification.Builder builder,
2311a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            boolean isLowPriority) {
2321a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        RemoteViews bigContentView = builder.createBigContentView();
2331a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        if (bigContentView != null) {
2341a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            return bigContentView;
2351a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2361a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        if (isLowPriority) {
2371a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            RemoteViews contentView = builder.createContentView();
2381a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            Notification.Builder.makeHeaderExpanded(contentView);
2391a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            return contentView;
2401a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2411a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        return null;
2421a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2431a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2441a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private RemoteViews createContentView(Notification.Builder builder,
2451a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            boolean isLowPriority, boolean useLarge) {
2461a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        if (isLowPriority) {
2471a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            return builder.makeLowPriorityContentView(false /* useRegularSubtext */);
2481a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2491a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        return builder.createContentView(useLarge);
2501a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2511a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2521a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    // Returns true if the RemoteViews are the same.
2531a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private boolean compareRemoteViews(final RemoteViews a, final RemoteViews b) {
2541a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        return (a == null && b == null) ||
2551a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                (a != null && b != null
2561a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && b.getPackage() != null
2571a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && a.getPackage() != null
2581a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && a.getPackage().equals(b.getPackage())
2591a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && a.getLayoutId() == b.getLayoutId());
2601a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
261c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
262c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    public void setInflateExceptionHandler(InflationExceptionHandler inflateExceptionHandler) {
263c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        mInflateExceptionHandler = inflateExceptionHandler;
264c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
265c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
266c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    public interface InflationExceptionHandler {
267c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        void handleInflationException(StatusBarNotification notification, InflationException e);
268c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
26910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek
2701a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void onDensityOrFontScaleChanged() {
2711a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        NotificationData.Entry entry = mRow.getEntry();
2721a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedAmbientContentView = null;
2731a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedBigContentView = null;
2741a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedContentView = null;
2751a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedHeadsUpContentView = null;
2761a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedPublicContentView = null;
2771a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        try {
2781a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            inflateNotificationViews();
2791a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        } catch (InflationException e) {
2801a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            mInflateExceptionHandler.handleInflationException(
2811a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                    mRow.getStatusBarNotification(), e);
2821a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2831a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2841a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2851a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek}
286