Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63115dc4 authored by Steve Elliott's avatar Steve Elliott
Browse files

Fix PeopleHub UI population once visually full

Bug: 149925807
Test: manual, atest
Change-Id: I21d043c7493698838f41fba9039e85783b961c95
parent b0940383
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -19,7 +19,13 @@ package com.android.systemui.statusbar.notification.people
import android.app.PendingIntent
import android.graphics.drawable.Drawable

/** `ViewModel` for PeopleHub view. */
/**
 * `ViewModel` for PeopleHub view.
 *
 * @param people ViewModels for individual people in PeopleHub, in order that they should be
 *  displayed
 * @param isVisible Whether or not the whole PeopleHub UI is visible
 **/
data class PeopleHubViewModel(val people: Sequence<PersonViewModel>, val isVisible: Boolean)

/** `ViewModel` for a single "Person' in PeopleHub. */
@@ -29,7 +35,11 @@ data class PersonViewModel(
    val onClick: () -> Unit
)

/** `Model` for PeopleHub. */
/**
 * `Model` for PeopleHub.
 *
 * @param people Models for individual people in PeopleHub, in order that they should be displayed
 **/
data class PeopleHubModel(val people: Collection<PersonModel>)

/** `Model` for a single "Person" in PeopleHub. */
+4 −1
Original line number Diff line number Diff line
@@ -195,7 +195,10 @@ private fun NotificationLockscreenUserManager.registerListener(

class PeopleHubManager {

    // People currently visible in the notification shade, and so are not in the hub
    private val activePeople = mutableMapOf<PersonKey, PersonModel>()

    // People that were once "active" and have been dismissed, and so can be displayed in the hub
    private val inactivePeople = ArrayDeque<PersonModel>(MAX_STORED_INACTIVE_PEOPLE)

    fun removeActivePerson(key: PersonKey): Boolean {
@@ -203,7 +206,7 @@ class PeopleHubManager {
            if (inactivePeople.size >= MAX_STORED_INACTIVE_PEOPLE) {
                inactivePeople.removeLast()
            }
            inactivePeople.add(data)
            inactivePeople.addFirst(data)
            return true
        }
        return false
+10 −3
Original line number Diff line number Diff line
@@ -38,7 +38,14 @@ interface PeopleHubViewBoundary {
    /** View used for animating the activity launch caused by clicking a person in the hub. */
    val associatedViewForClickAnimation: View

    /** [DataListener]s for individual people in the hub. */
    /**
     * [DataListener]s for individual people in the hub.
     *
     * These listeners should be ordered such that the first element will be bound to the most
     * recent person to be added to the hub, and then continuing in descending order. If there are
     * not enough people to satisfy each listener, `null` will be passed instead, indicating that
     * the `View` should render a placeholder.
     */
    val personViewAdapters: Sequence<DataListener<PersonViewModel?>>

    /** Sets the visibility of the Hub in the notification shade. */
@@ -80,8 +87,8 @@ private class PeopleHubDataListenerImpl(
        )
        viewBoundary.setVisible(viewModel.isVisible)
        val padded = viewModel.people + repeated(null)
        for ((personAdapter, personModel) in viewBoundary.personViewAdapters.zip(padded)) {
            personAdapter.onDataChanged(personModel)
        for ((adapter, model) in viewBoundary.personViewAdapters.zip(padded)) {
            adapter.onDataChanged(model)
        }
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -38,13 +38,13 @@ class PeopleHubView(context: Context, attrs: AttributeSet) :
    override fun onFinishInflate() {
        contents = requireViewById(R.id.people_list)
        personViewAdapters = (0 until contents.childCount)
                .reversed()
                .asSequence()
                .asSequence() // so we can map
                .mapNotNull { idx ->
                    // get all our people slots
                    (contents.getChildAt(idx) as? ImageView)?.let(::PersonDataListenerImpl)
                }
                .toList()
                .asSequence()
                .toList() // cache it
                .asSequence() // but don't reveal it's a list
        super.onFinishInflate()
        setVisible(true /* nowVisible */, false /* animate */)
    }
@@ -80,6 +80,7 @@ class PeopleHubView(context: Context, attrs: AttributeSet) :
            DataListener<PersonViewModel?> {

        override fun onDataChanged(data: PersonViewModel?) {
            avatarView.visibility = data?.let { View.VISIBLE } ?: View.GONE
            avatarView.setImageDrawable(data?.icon)
            avatarView.setOnClickListener { data?.onClick?.invoke() }
        }
+31 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.people

object EmptySubscription : Subscription {
    override fun unsubscribe() {}
}

class FakeDataSource<T>(
    private val data: T,
    private val subscription: Subscription = EmptySubscription
) : DataSource<T> {
    override fun registerListener(listener: DataListener<T>): Subscription {
        listener.onDataChanged(data)
        return subscription
    }
}
 No newline at end of file
Loading