diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java index 66703ee632191..73eecbbf27288 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java @@ -23,19 +23,19 @@ import android.util.Log; import android.view.View; import android.widget.RemoteViews; +import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationContentView; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.phone.StatusBar; -import java.util.Objects; - /** * A utility that inflates the right kind of contentView based on the state */ public class NotificationInflater { - private static final int FLAG_REINFLATE_ALL = ~0; + @VisibleForTesting + static final int FLAG_REINFLATE_ALL = ~0; private static final int FLAG_REINFLATE_CONTENT_VIEW = 1<<0; private static final int FLAG_REINFLATE_EXPANDED_VIEW = 1<<1; private static final int FLAG_REINFLATE_HEADS_UP_VIEW = 1<<2; @@ -104,115 +104,12 @@ public class NotificationInflater { */ private void inflateNotificationViews(int reInflateFlags) throws InflationException { - NotificationData.Entry entry = mRow.getEntry(); - StatusBarNotification sbn = entry.notification; - Context context = mRow.getContext(); - NotificationContentView privateLayout = mRow.getPrivateLayout(); + StatusBarNotification sbn = mRow.getEntry().notification; try { final Notification.Builder recoveredBuilder - = Notification.Builder.recoverBuilder(context, sbn.getNotification()); - boolean isLowPriority = mIsLowPriority && !mIsChildInGroup; - if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) { - final RemoteViews newContentView = createContentView(recoveredBuilder, - isLowPriority, mUsesIncreasedHeadsUpHeight); - if (!compareRemoteViews(newContentView, - entry.cachedContentView)) { - View contentViewLocal = newContentView.apply( - sbn.getPackageContext(context), - privateLayout, - mRemoteViewClickHandler); - contentViewLocal.setIsRootNamespace(true); - privateLayout.setContractedChild(contentViewLocal); - } else { - newContentView.reapply(sbn.getPackageContext(context), - privateLayout.getContractedChild(), - mRemoteViewClickHandler); - } - entry.cachedContentView = newContentView; - } - - if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) { - final RemoteViews newBigContentView = createBigContentView( - recoveredBuilder, isLowPriority); - if (newBigContentView != null) { - if (!compareRemoteViews(newBigContentView, entry.cachedBigContentView)) { - View bigContentViewLocal = newBigContentView.apply( - sbn.getPackageContext(context), - privateLayout, - mRemoteViewClickHandler); - bigContentViewLocal.setIsRootNamespace(true); - privateLayout.setExpandedChild(bigContentViewLocal); - } else { - newBigContentView.reapply(sbn.getPackageContext(context), - privateLayout.getExpandedChild(), - mRemoteViewClickHandler); - } - } else if (entry.cachedBigContentView != null) { - privateLayout.setExpandedChild(null); - } - entry.cachedBigContentView = newBigContentView; - mRow.setExpandable(newBigContentView != null); - } - - if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) { - final RemoteViews newHeadsUpContentView = - recoveredBuilder.createHeadsUpContentView(mUsesIncreasedHeight); - if (newHeadsUpContentView != null) { - if (!compareRemoteViews(newHeadsUpContentView, - entry.cachedHeadsUpContentView)) { - View headsUpContentViewLocal = newHeadsUpContentView.apply( - sbn.getPackageContext(context), - privateLayout, - mRemoteViewClickHandler); - headsUpContentViewLocal.setIsRootNamespace(true); - privateLayout.setHeadsUpChild(headsUpContentViewLocal); - } else { - newHeadsUpContentView.reapply(sbn.getPackageContext(context), - privateLayout.getHeadsUpChild(), - mRemoteViewClickHandler); - } - } else if (entry.cachedHeadsUpContentView != null) { - privateLayout.setHeadsUpChild(null); - } - entry.cachedHeadsUpContentView = newHeadsUpContentView; - } - - if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) { - NotificationContentView publicLayout = mRow.getPublicLayout(); - final RemoteViews newPublicNotification - = recoveredBuilder.makePublicContentView(); - if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) { - View publicContentView = newPublicNotification.apply( - sbn.getPackageContext(context), - publicLayout, - mRemoteViewClickHandler); - publicContentView.setIsRootNamespace(true); - publicLayout.setContractedChild(publicContentView); - } else { - newPublicNotification.reapply(sbn.getPackageContext(context), - publicLayout.getContractedChild(), - mRemoteViewClickHandler); - } - entry.cachedPublicContentView = newPublicNotification; - } - - if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) { - final RemoteViews newAmbientNotification - = recoveredBuilder.makeAmbientNotification(); - if (!compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) { - View ambientContentView = newAmbientNotification.apply( - sbn.getPackageContext(context), - privateLayout, - mRemoteViewClickHandler); - ambientContentView.setIsRootNamespace(true); - privateLayout.setAmbientChild(ambientContentView); - } else { - newAmbientNotification.reapply(sbn.getPackageContext(context), - privateLayout.getAmbientChild(), - mRemoteViewClickHandler); - } - entry.cachedAmbientContentView = newAmbientNotification; - } + = Notification.Builder.recoverBuilder(mRow.getContext(), sbn.getNotification()); + Context packageContext = sbn.getPackageContext(mRow.getContext()); + inflateNotificationViews(reInflateFlags, recoveredBuilder, packageContext); } catch (RuntimeException e) { final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()); @@ -221,6 +118,115 @@ public class NotificationInflater { } } + @VisibleForTesting + void inflateNotificationViews(int reInflateFlags, + Notification.Builder builder, Context packageContext) { + NotificationData.Entry entry = mRow.getEntry(); + NotificationContentView privateLayout = mRow.getPrivateLayout(); + boolean isLowPriority = mIsLowPriority && !mIsChildInGroup; + if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) { + final RemoteViews newContentView = createContentView(builder, + isLowPriority, mUsesIncreasedHeight); + if (!compareRemoteViews(newContentView, + entry.cachedContentView)) { + View contentViewLocal = newContentView.apply( + packageContext, + privateLayout, + mRemoteViewClickHandler); + contentViewLocal.setIsRootNamespace(true); + privateLayout.setContractedChild(contentViewLocal); + } else { + newContentView.reapply(packageContext, + privateLayout.getContractedChild(), + mRemoteViewClickHandler); + } + entry.cachedContentView = newContentView; + } + + if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) { + final RemoteViews newBigContentView = createBigContentView( + builder, isLowPriority); + if (newBigContentView != null) { + if (!compareRemoteViews(newBigContentView, entry.cachedBigContentView)) { + View bigContentViewLocal = newBigContentView.apply( + packageContext, + privateLayout, + mRemoteViewClickHandler); + bigContentViewLocal.setIsRootNamespace(true); + privateLayout.setExpandedChild(bigContentViewLocal); + } else { + newBigContentView.reapply(packageContext, + privateLayout.getExpandedChild(), + mRemoteViewClickHandler); + } + } else if (entry.cachedBigContentView != null) { + privateLayout.setExpandedChild(null); + } + entry.cachedBigContentView = newBigContentView; + mRow.setExpandable(newBigContentView != null); + } + + if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) { + final RemoteViews newHeadsUpContentView = + builder.createHeadsUpContentView(mUsesIncreasedHeadsUpHeight); + if (newHeadsUpContentView != null) { + if (!compareRemoteViews(newHeadsUpContentView, + entry.cachedHeadsUpContentView)) { + View headsUpContentViewLocal = newHeadsUpContentView.apply( + packageContext, + privateLayout, + mRemoteViewClickHandler); + headsUpContentViewLocal.setIsRootNamespace(true); + privateLayout.setHeadsUpChild(headsUpContentViewLocal); + } else { + newHeadsUpContentView.reapply(packageContext, + privateLayout.getHeadsUpChild(), + mRemoteViewClickHandler); + } + } else if (entry.cachedHeadsUpContentView != null) { + privateLayout.setHeadsUpChild(null); + } + entry.cachedHeadsUpContentView = newHeadsUpContentView; + } + + if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) { + NotificationContentView publicLayout = mRow.getPublicLayout(); + final RemoteViews newPublicNotification + = builder.makePublicContentView(); + if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) { + View publicContentView = newPublicNotification.apply( + packageContext, + publicLayout, + mRemoteViewClickHandler); + publicContentView.setIsRootNamespace(true); + publicLayout.setContractedChild(publicContentView); + } else { + newPublicNotification.reapply(packageContext, + publicLayout.getContractedChild(), + mRemoteViewClickHandler); + } + entry.cachedPublicContentView = newPublicNotification; + } + + if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) { + final RemoteViews newAmbientNotification + = builder.makeAmbientNotification(); + if (!compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) { + View ambientContentView = newAmbientNotification.apply( + packageContext, + privateLayout, + mRemoteViewClickHandler); + ambientContentView.setIsRootNamespace(true); + privateLayout.setAmbientChild(ambientContentView); + } else { + newAmbientNotification.reapply(packageContext, + privateLayout.getAmbientChild(), + mRemoteViewClickHandler); + } + entry.cachedAmbientContentView = newAmbientNotification; + } + } + private RemoteViews createBigContentView(Notification.Builder builder, boolean isLowPriority) { RemoteViews bigContentView = builder.createBigContentView(); @@ -260,6 +266,7 @@ public class NotificationInflater { public interface InflationExceptionHandler { void handleInflationException(StatusBarNotification notification, InflationException e); } + public void onDensityOrFontScaleChanged() { NotificationData.Entry entry = mRow.getEntry(); entry.cachedAmbientContentView = null; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java index 96dbdb36b5a46..c91b269d6329e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java @@ -42,12 +42,6 @@ public class NotificationTestHelper { } public ExpandableNotificationRow createRow() { - LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( - mContext.LAYOUT_INFLATER_SERVICE); - ExpandableNotificationRow row = (ExpandableNotificationRow) inflater.inflate( - R.layout.status_bar_notification_row, - null, false); - row.setGroupManager(mGroupManager); Notification publicVersion = new Notification.Builder(mContext).setSmallIcon( R.drawable.ic_person) .setCustomContentView(new RemoteViews(mContext.getPackageName(), @@ -59,6 +53,16 @@ public class NotificationTestHelper { .setContentText("Text") .setPublicVersion(publicVersion) .build(); + return createRow(notification); + } + + public ExpandableNotificationRow createRow(Notification notification) { + LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( + mContext.LAYOUT_INFLATER_SERVICE); + ExpandableNotificationRow row = (ExpandableNotificationRow) inflater.inflate( + R.layout.status_bar_notification_row, + null, false); + row.setGroupManager(mGroupManager); UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser()); StatusBarNotification sbn = new StatusBarNotification("com.android.systemui", "com.android.systemui", mId++, null, 1000, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationinflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationinflaterTest.java new file mode 100644 index 0000000000000..0ec9c106a5964 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationinflaterTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.notification; + +import static com.android.systemui.statusbar.notification.NotificationInflater.FLAG_REINFLATE_ALL; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.app.Notification; +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.annotation.UiThreadTest; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import com.android.systemui.R; +import com.android.systemui.statusbar.ExpandableNotificationRow; +import com.android.systemui.statusbar.NotificationTestHelper; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class NotificationinflaterTest { + + private Context mContext; + private NotificationInflater mNotificationInflater; + private Notification.Builder mBuilder; + + @Before + @UiThreadTest + public void setUp() { + mContext = InstrumentationRegistry.getTargetContext(); + mBuilder = new Notification.Builder(mContext).setSmallIcon( + R.drawable.ic_person) + .setContentTitle("Title") + .setContentText("Text"); + ExpandableNotificationRow row = new NotificationTestHelper(mContext).createRow( + mBuilder.build()); + mNotificationInflater = new NotificationInflater(row); + } + + @Test + public void testIncreasedHeadsUpBeingUsed() { + mNotificationInflater.setUsesIncreasedHeadsUpHeight(true); + Notification.Builder builder = spy(mBuilder); + mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext); + verify(builder).createHeadsUpContentView(true); + } + + @Test + public void testIncreasedHeightBeingUsed() { + mNotificationInflater.setUsesIncreasedHeight(true); + Notification.Builder builder = spy(mBuilder); + mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext); + verify(builder).createContentView(true); + } +}