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