Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +31 −2 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.UnlockMethodCache; import com.android.systemui.util.Assert; import java.util.ArrayList; import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; Loading Loading @@ -86,6 +86,9 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle private NotificationPresenter mPresenter; private NotificationPresenter mPresenter; private NotificationListContainer mListContainer; private NotificationListContainer mListContainer; // Used to help track down re-entrant calls to our update methods, which will cause bugs. private boolean mPerformingUpdate; @Inject @Inject public NotificationViewHierarchyManager(Context context, public NotificationViewHierarchyManager(Context context, NotificationLockscreenUserManager notificationLockscreenUserManager, NotificationLockscreenUserManager notificationLockscreenUserManager, Loading Loading @@ -123,6 +126,9 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle */ */ //TODO: Rewrite this to focus on Entries, or some other data object instead of views //TODO: Rewrite this to focus on Entries, or some other data object instead of views public void updateNotificationViews() { public void updateNotificationViews() { Assert.isMainThread(); beginUpdate(); ArrayList<NotificationEntry> activeNotifications = mEntryManager.getNotificationData() ArrayList<NotificationEntry> activeNotifications = mEntryManager.getNotificationData() .getActiveNotifications(); .getActiveNotifications(); ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size()); ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size()); Loading Loading @@ -248,9 +254,11 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle // clear the map again for the next usage // clear the map again for the next usage mTmpChildOrderMap.clear(); mTmpChildOrderMap.clear(); updateRowStates(); updateRowStatesInternal(); mListContainer.onNotificationViewUpdateFinished(); mListContainer.onNotificationViewUpdateFinished(); endUpdate(); } } private void addNotificationChildrenAndSort() { private void addNotificationChildrenAndSort() { Loading Loading @@ -334,6 +342,13 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle * Updates expanded, dimmed and locked states of notification rows. * Updates expanded, dimmed and locked states of notification rows. */ */ public void updateRowStates() { public void updateRowStates() { Assert.isMainThread(); beginUpdate(); updateRowStatesInternal(); endUpdate(); } private void updateRowStatesInternal() { Trace.beginSection("NotificationViewHierarchyManager#updateRowStates"); Trace.beginSection("NotificationViewHierarchyManager#updateRowStates"); final int N = mListContainer.getContainerChildCount(); final int N = mListContainer.getContainerChildCount(); Loading Loading @@ -425,4 +440,18 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle public void onDynamicPrivacyChanged() { public void onDynamicPrivacyChanged() { updateNotificationViews(); updateNotificationViews(); } } private void beginUpdate() { if (mPerformingUpdate) { throw new IllegalStateException("Re-entrant code during update."); } mPerformingUpdate = true; } private void endUpdate() { if (!mPerformingUpdate) { throw new IllegalStateException("Manager state has become desynced."); } mPerformingUpdate = false; } } } packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -141,6 +141,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController.Configurati import com.android.systemui.statusbar.policy.HeadsUpUtil; import com.android.systemui.statusbar.policy.HeadsUpUtil; import com.android.systemui.statusbar.policy.ScrollAdapter; import com.android.systemui.statusbar.policy.ScrollAdapter; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService; import com.android.systemui.util.Assert; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; Loading Loading @@ -2855,6 +2856,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void setChildTransferInProgress(boolean childTransferInProgress) { public void setChildTransferInProgress(boolean childTransferInProgress) { Assert.isMainThread(); mChildTransferInProgress = childTransferInProgress; mChildTransferInProgress = childTransferInProgress; } } Loading Loading @@ -3298,6 +3300,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd @Override @Override @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) public void changeViewPosition(ExpandableView child, int newIndex) { public void changeViewPosition(ExpandableView child, int newIndex) { Assert.isMainThread(); if (mChangePositionInProgress) { throw new IllegalStateException("Reentrant call to changeViewPosition"); } int currentIndex = indexOfChild(child); int currentIndex = indexOfChild(child); if (currentIndex == -1) { if (currentIndex == -1) { Loading Loading @@ -4992,12 +4999,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd @Override @Override @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void removeContainerView(View v) { public void removeContainerView(View v) { Assert.isMainThread(); removeView(v); removeView(v); } } @Override @Override @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void addContainerView(View v) { public void addContainerView(View v) { Assert.isMainThread(); addView(v); addView(v); } } Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +6 −2 Original line number Original line Diff line number Diff line Loading @@ -38,11 +38,12 @@ import static org.mockito.Mockito.when; import android.metrics.LogMaker; import android.metrics.LogMaker; import android.provider.Settings; import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; import android.view.View; import androidx.test.annotation.UiThreadTest; import androidx.test.annotation.UiThreadTest; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto; Loading Loading @@ -95,7 +96,8 @@ import java.util.ArrayList; * Tests for {@link NotificationStackScrollLayout}. * Tests for {@link NotificationStackScrollLayout}. */ */ @SmallTest @SmallTest @RunWith(AndroidJUnit4.class) @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class NotificationStackScrollLayoutTest extends SysuiTestCase { public class NotificationStackScrollLayoutTest extends SysuiTestCase { private NotificationStackScrollLayout mStackScroller; // Normally test this private NotificationStackScrollLayout mStackScroller; // Normally test this Loading Loading @@ -123,6 +125,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Before @Before @UiThreadTest @UiThreadTest public void setUp() throws Exception { public void setUp() throws Exception { com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper(); mOriginalInterruptionModelSetting = Settings.Secure.getInt(mContext.getContentResolver(), mOriginalInterruptionModelSetting = Settings.Secure.getInt(mContext.getContentResolver(), NOTIFICATION_NEW_INTERRUPTION_MODEL, 0); NOTIFICATION_NEW_INTERRUPTION_MODEL, 0); Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.putInt(mContext.getContentResolver(), Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +31 −2 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.UnlockMethodCache; import com.android.systemui.util.Assert; import java.util.ArrayList; import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; Loading Loading @@ -86,6 +86,9 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle private NotificationPresenter mPresenter; private NotificationPresenter mPresenter; private NotificationListContainer mListContainer; private NotificationListContainer mListContainer; // Used to help track down re-entrant calls to our update methods, which will cause bugs. private boolean mPerformingUpdate; @Inject @Inject public NotificationViewHierarchyManager(Context context, public NotificationViewHierarchyManager(Context context, NotificationLockscreenUserManager notificationLockscreenUserManager, NotificationLockscreenUserManager notificationLockscreenUserManager, Loading Loading @@ -123,6 +126,9 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle */ */ //TODO: Rewrite this to focus on Entries, or some other data object instead of views //TODO: Rewrite this to focus on Entries, or some other data object instead of views public void updateNotificationViews() { public void updateNotificationViews() { Assert.isMainThread(); beginUpdate(); ArrayList<NotificationEntry> activeNotifications = mEntryManager.getNotificationData() ArrayList<NotificationEntry> activeNotifications = mEntryManager.getNotificationData() .getActiveNotifications(); .getActiveNotifications(); ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size()); ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size()); Loading Loading @@ -248,9 +254,11 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle // clear the map again for the next usage // clear the map again for the next usage mTmpChildOrderMap.clear(); mTmpChildOrderMap.clear(); updateRowStates(); updateRowStatesInternal(); mListContainer.onNotificationViewUpdateFinished(); mListContainer.onNotificationViewUpdateFinished(); endUpdate(); } } private void addNotificationChildrenAndSort() { private void addNotificationChildrenAndSort() { Loading Loading @@ -334,6 +342,13 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle * Updates expanded, dimmed and locked states of notification rows. * Updates expanded, dimmed and locked states of notification rows. */ */ public void updateRowStates() { public void updateRowStates() { Assert.isMainThread(); beginUpdate(); updateRowStatesInternal(); endUpdate(); } private void updateRowStatesInternal() { Trace.beginSection("NotificationViewHierarchyManager#updateRowStates"); Trace.beginSection("NotificationViewHierarchyManager#updateRowStates"); final int N = mListContainer.getContainerChildCount(); final int N = mListContainer.getContainerChildCount(); Loading Loading @@ -425,4 +440,18 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle public void onDynamicPrivacyChanged() { public void onDynamicPrivacyChanged() { updateNotificationViews(); updateNotificationViews(); } } private void beginUpdate() { if (mPerformingUpdate) { throw new IllegalStateException("Re-entrant code during update."); } mPerformingUpdate = true; } private void endUpdate() { if (!mPerformingUpdate) { throw new IllegalStateException("Manager state has become desynced."); } mPerformingUpdate = false; } } }
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -141,6 +141,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController.Configurati import com.android.systemui.statusbar.policy.HeadsUpUtil; import com.android.systemui.statusbar.policy.HeadsUpUtil; import com.android.systemui.statusbar.policy.ScrollAdapter; import com.android.systemui.statusbar.policy.ScrollAdapter; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService; import com.android.systemui.util.Assert; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; Loading Loading @@ -2855,6 +2856,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void setChildTransferInProgress(boolean childTransferInProgress) { public void setChildTransferInProgress(boolean childTransferInProgress) { Assert.isMainThread(); mChildTransferInProgress = childTransferInProgress; mChildTransferInProgress = childTransferInProgress; } } Loading Loading @@ -3298,6 +3300,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd @Override @Override @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER) public void changeViewPosition(ExpandableView child, int newIndex) { public void changeViewPosition(ExpandableView child, int newIndex) { Assert.isMainThread(); if (mChangePositionInProgress) { throw new IllegalStateException("Reentrant call to changeViewPosition"); } int currentIndex = indexOfChild(child); int currentIndex = indexOfChild(child); if (currentIndex == -1) { if (currentIndex == -1) { Loading Loading @@ -4992,12 +4999,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd @Override @Override @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void removeContainerView(View v) { public void removeContainerView(View v) { Assert.isMainThread(); removeView(v); removeView(v); } } @Override @Override @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void addContainerView(View v) { public void addContainerView(View v) { Assert.isMainThread(); addView(v); addView(v); } } Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +6 −2 Original line number Original line Diff line number Diff line Loading @@ -38,11 +38,12 @@ import static org.mockito.Mockito.when; import android.metrics.LogMaker; import android.metrics.LogMaker; import android.provider.Settings; import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; import android.view.View; import androidx.test.annotation.UiThreadTest; import androidx.test.annotation.UiThreadTest; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto; Loading Loading @@ -95,7 +96,8 @@ import java.util.ArrayList; * Tests for {@link NotificationStackScrollLayout}. * Tests for {@link NotificationStackScrollLayout}. */ */ @SmallTest @SmallTest @RunWith(AndroidJUnit4.class) @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class NotificationStackScrollLayoutTest extends SysuiTestCase { public class NotificationStackScrollLayoutTest extends SysuiTestCase { private NotificationStackScrollLayout mStackScroller; // Normally test this private NotificationStackScrollLayout mStackScroller; // Normally test this Loading Loading @@ -123,6 +125,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { @Before @Before @UiThreadTest @UiThreadTest public void setUp() throws Exception { public void setUp() throws Exception { com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper(); mOriginalInterruptionModelSetting = Settings.Secure.getInt(mContext.getContentResolver(), mOriginalInterruptionModelSetting = Settings.Secure.getInt(mContext.getContentResolver(), NOTIFICATION_NEW_INTERRUPTION_MODEL, 0); NOTIFICATION_NEW_INTERRUPTION_MODEL, 0); Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.putInt(mContext.getContentResolver(), Loading