NotificationInflater.java revision 1a1ecfcf5ae32482aee23ebc7c4389daf164cadd
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;
241a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roosimport android.view.ViewGroup;
251a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roosimport android.view.ViewParent;
261a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport android.widget.RemoteViews;
271a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinekimport com.android.internal.annotations.VisibleForTesting;
291a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.ExpandableNotificationRow;
301a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.NotificationContentView;
311a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.NotificationData;
321a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekimport com.android.systemui.statusbar.phone.StatusBar;
331a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
341a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek/**
351a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek * A utility that inflates the right kind of contentView based on the state
361a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek */
371a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinekpublic class NotificationInflater {
381a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
3910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    @VisibleForTesting
4010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    static final int FLAG_REINFLATE_ALL = ~0;
41c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private static final int FLAG_REINFLATE_CONTENT_VIEW = 1<<0;
42c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private 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;
53c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private InflationExceptionHandler mInflateExceptionHandler;
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     */
69c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    public boolean setIsChildInGroup(boolean childInGroup) {
70c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        if (childInGroup != mIsChildInGroup) {
71c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            mIsChildInGroup = childInGroup;
72c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            if (mIsLowPriority) {
73c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                try {
74c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                    int flags = FLAG_REINFLATE_CONTENT_VIEW | FLAG_REINFLATE_EXPANDED_VIEW;
75c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                    inflateNotificationViews(flags);
76c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                } catch (InflationException e) {
77c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                    mInflateExceptionHandler.handleInflationException(
78c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                            mRow.getStatusBarNotification(), e);
79c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek                }
80c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            }
81c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            return true;
82c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        }
83c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        return false;
84c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
85c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
861a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setUsesIncreasedHeight(boolean usesIncreasedHeight) {
871a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mUsesIncreasedHeight = usesIncreasedHeight;
881a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
891a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
901a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setUsesIncreasedHeadsUpHeight(boolean usesIncreasedHeight) {
911a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mUsesIncreasedHeadsUpHeight = usesIncreasedHeight;
921a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
931a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
941a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void setRemoteViewClickHandler(RemoteViews.OnClickHandler remoteViewClickHandler) {
951a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        mRemoteViewClickHandler = remoteViewClickHandler;
961a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
971a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
981a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos    public void setRedactAmbient(boolean redactAmbient) {
991a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos        if (mRedactAmbient != redactAmbient) {
1001a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            mRedactAmbient = redactAmbient;
1011a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            if (mRow.getEntry() == null) {
1021a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                return;
1031a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            }
1041a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            try {
1051a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                inflateNotificationViews(FLAG_REINFLATE_AMBIENT_VIEW);
1061a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            } catch (InflationException e) {
1071a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                mInflateExceptionHandler.handleInflationException(
1081a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                        mRow.getStatusBarNotification(), e);
1091a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            }
1101a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos        }
1111a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos    }
1121a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos
1131a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void inflateNotificationViews() throws InflationException {
114c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        inflateNotificationViews(FLAG_REINFLATE_ALL);
115c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
116c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
117c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    /**
118c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * reinflate all views for the specified flags
119c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * @param reInflateFlags flags which views should be reinflated. Use {@link #FLAG_REINFLATE_ALL}
120c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     *                       to reinflate all of views.
121c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     * @throws InflationException
122c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek     */
123c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    private void inflateNotificationViews(int reInflateFlags)
124c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            throws InflationException {
12510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        StatusBarNotification sbn = mRow.getEntry().notification;
1261a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        try {
1271a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            final Notification.Builder recoveredBuilder
12810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    = Notification.Builder.recoverBuilder(mRow.getContext(), sbn.getNotification());
12910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            Context packageContext = sbn.getPackageContext(mRow.getContext());
13010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            inflateNotificationViews(reInflateFlags, recoveredBuilder, packageContext);
1311a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
13210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        } catch (RuntimeException e) {
13310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
13410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
13510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            throw new InflationException("Couldn't inflate contentViews");
13610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
13710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    }
1381a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
13910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    @VisibleForTesting
14010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek    void inflateNotificationViews(int reInflateFlags,
14110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            Notification.Builder builder, Context packageContext) {
14210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        NotificationData.Entry entry = mRow.getEntry();
14310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        NotificationContentView privateLayout = mRow.getPrivateLayout();
1441a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos        NotificationContentView publicLayout = mRow.getPublicLayout();
1451a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos
14610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        boolean isLowPriority = mIsLowPriority && !mIsChildInGroup;
14710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
14810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newContentView = createContentView(builder,
14910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    isLowPriority, mUsesIncreasedHeight);
15010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (!compareRemoteViews(newContentView,
15110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    entry.cachedContentView)) {
15210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                View contentViewLocal = newContentView.apply(
15310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        packageContext,
15410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        privateLayout,
15510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
15610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                contentViewLocal.setIsRootNamespace(true);
15710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setContractedChild(contentViewLocal);
15810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else {
15910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                newContentView.reapply(packageContext,
16010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        privateLayout.getContractedChild(),
16110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
162c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek            }
16310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedContentView = newContentView;
16410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
165c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
16610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
16710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newBigContentView = createBigContentView(
16810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    builder, isLowPriority);
16910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (newBigContentView != null) {
17010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                if (!compareRemoteViews(newBigContentView, entry.cachedBigContentView)) {
17110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    View bigContentViewLocal = newBigContentView.apply(
17210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            packageContext,
17310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            privateLayout,
1741a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
17510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    bigContentViewLocal.setIsRootNamespace(true);
17610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    privateLayout.setExpandedChild(bigContentViewLocal);
1771a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                } else {
17810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    newBigContentView.reapply(packageContext,
17910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            privateLayout.getExpandedChild(),
1801a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
1811a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                }
18210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else if (entry.cachedBigContentView != null) {
18310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setExpandedChild(null);
1841a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            }
18510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedBigContentView = newBigContentView;
18610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            mRow.setExpandable(newBigContentView != null);
18710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
1881a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
18910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
19010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newHeadsUpContentView =
19110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    builder.createHeadsUpContentView(mUsesIncreasedHeadsUpHeight);
19210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (newHeadsUpContentView != null) {
19310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                if (!compareRemoteViews(newHeadsUpContentView,
19410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        entry.cachedHeadsUpContentView)) {
19510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    View headsUpContentViewLocal = newHeadsUpContentView.apply(
19610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            packageContext,
1971a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            privateLayout,
1981a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
19910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    headsUpContentViewLocal.setIsRootNamespace(true);
20010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    privateLayout.setHeadsUpChild(headsUpContentViewLocal);
2011a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                } else {
20210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    newHeadsUpContentView.reapply(packageContext,
20310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                            privateLayout.getHeadsUpChild(),
2041a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                            mRemoteViewClickHandler);
2051a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                }
20610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else if (entry.cachedHeadsUpContentView != null) {
20710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                privateLayout.setHeadsUpChild(null);
2081a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            }
20910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedHeadsUpContentView = newHeadsUpContentView;
21010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
2111a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
21210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
21310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            final RemoteViews newPublicNotification
21410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                    = builder.makePublicContentView();
21510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) {
21610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                View publicContentView = newPublicNotification.apply(
21710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        packageContext,
21810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        publicLayout,
21910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
22010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                publicContentView.setIsRootNamespace(true);
22110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                publicLayout.setContractedChild(publicContentView);
22210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else {
22310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                newPublicNotification.reapply(packageContext,
22410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        publicLayout.getContractedChild(),
22510790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
22610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            }
22710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedPublicContentView = newPublicNotification;
22810790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        }
22910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek
23010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek        if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
2311a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            final RemoteViews newAmbientNotification = mRedactAmbient
2321a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                    ? builder.makePublicAmbientNotification()
2331a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                    : builder.makeAmbientNotification();
2341a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            NotificationContentView newParent = mRedactAmbient ? publicLayout : privateLayout;
2351a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            NotificationContentView otherParent = !mRedactAmbient ? publicLayout : privateLayout;
2361a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos
2371a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos            if (newParent.getAmbientChild() == null ||
2381a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                    !compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) {
23910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                View ambientContentView = newAmbientNotification.apply(
24010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        packageContext,
2411a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                        newParent,
24210790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
24310790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                ambientContentView.setIsRootNamespace(true);
2441a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                newParent.setAmbientChild(ambientContentView);
2451a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                otherParent.setAmbientChild(null);
24610790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            } else {
24710790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                newAmbientNotification.reapply(packageContext,
2481a1ecfcf5ae32482aee23ebc7c4389daf164caddAdrian Roos                        newParent.getAmbientChild(),
24910790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek                        mRemoteViewClickHandler);
25010790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            }
25110790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek            entry.cachedAmbientContentView = newAmbientNotification;
2521a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2531a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2541a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2551a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private RemoteViews createBigContentView(Notification.Builder builder,
2561a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            boolean isLowPriority) {
2571a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        RemoteViews bigContentView = builder.createBigContentView();
2581a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        if (bigContentView != null) {
2591a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            return bigContentView;
2601a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2611a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        if (isLowPriority) {
2621a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            RemoteViews contentView = builder.createContentView();
2631a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            Notification.Builder.makeHeaderExpanded(contentView);
2641a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            return contentView;
2651a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2661a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        return null;
2671a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2681a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2691a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private RemoteViews createContentView(Notification.Builder builder,
2701a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            boolean isLowPriority, boolean useLarge) {
2711a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        if (isLowPriority) {
2721a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            return builder.makeLowPriorityContentView(false /* useRegularSubtext */);
2731a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
2741a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        return builder.createContentView(useLarge);
2751a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
2761a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
2771a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    // Returns true if the RemoteViews are the same.
2781a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    private boolean compareRemoteViews(final RemoteViews a, final RemoteViews b) {
2791a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        return (a == null && b == null) ||
2801a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                (a != null && b != null
2811a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && b.getPackage() != null
2821a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && a.getPackage() != null
2831a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && a.getPackage().equals(b.getPackage())
2841a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                        && a.getLayoutId() == b.getLayoutId());
2851a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
286c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
287c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    public void setInflateExceptionHandler(InflationExceptionHandler inflateExceptionHandler) {
288c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        mInflateExceptionHandler = inflateExceptionHandler;
289c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
290c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek
291c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    public interface InflationExceptionHandler {
292c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek        void handleInflationException(StatusBarNotification notification, InflationException e);
293c478f9023d7649d85e60759c9e6c0e033774293bSelim Cinek    }
29410790672a98debafb8882971e94ff26aec9a6bfaSelim Cinek
2951a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    public void onDensityOrFontScaleChanged() {
2961a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        NotificationData.Entry entry = mRow.getEntry();
2971a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedAmbientContentView = null;
2981a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedBigContentView = null;
2991a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedContentView = null;
3001a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedHeadsUpContentView = null;
3011a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        entry.cachedPublicContentView = null;
3021a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        try {
3031a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            inflateNotificationViews();
3041a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        } catch (InflationException e) {
3051a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek            mInflateExceptionHandler.handleInflationException(
3061a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek                    mRow.getStatusBarNotification(), e);
3071a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek        }
3081a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek    }
3091a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek
3101a48babb5ed30e8a3eb9645355d6455b21041406Selim Cinek}
311