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