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

Commit 1061f45f authored by Evan Laird's avatar Evan Laird
Browse files

[Sb] Define a network slice UI for mobile icons

Based on the new flag NEW_NETWORK_SLICE_UI, we start collecting on
the value of the prioritized network information from the mobile
connection repository, and define a new background layer for the mobile
network type view.

Also reworked the mobile network type icon ImageView to be a FrameLayout
with a background layer. This change does add a small amount of extra
padding, which ensures that the actual slice background has enough space
to draw and doesn't cause the icon to widen when it is shown. We might
want to change this in the future to optimize more space away.

Test: MobileIconViewModelTest, ModernStatusBarMobileViewTest
Test: all sysui tests
Test: use the new `slice` field supported by demo mode
Bug: 270385675
Change-Id: I15be2651e0ceb7d053ce4513e58c207935769963
parent 35943915
Loading
Loading
Loading
Loading
+15 −8
Original line number Diff line number Diff line
@@ -52,15 +52,22 @@
                android:visibility="gone"
                />
        </FrameLayout>
        <FrameLayout
            android:id="@+id/mobile_type_container"
            android:layout_height="@dimen/status_bar_mobile_container_height"
            android:layout_width="wrap_content"
            android:layout_marginStart="2.5sp"
            android:layout_marginEnd="1sp"
            android:visibility="gone"
            >
            <ImageView
                android:id="@+id/mobile_type"
                android:layout_height="@dimen/status_bar_mobile_type_size"
                android:layout_width="wrap_content"
                android:layout_gravity="center_vertical"
                android:adjustViewBounds="true"
            android:paddingStart="2.5sp"
            android:paddingEnd="1sp"
            android:visibility="gone" />
                />
        </FrameLayout>
        <Space
            android:id="@+id/mobile_roaming_space"
            android:layout_height="match_parent"
+30 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?><!--
  ~ Copyright (C) 2023 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.
  ~
  -->

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <corners
        android:topLeftRadius="0dp"
        android:topRightRadius="@dimen/status_bar_mobile_container_corner_radius"
        android:bottomRightRadius="0dp"
        android:bottomLeftRadius="@dimen/status_bar_mobile_container_corner_radius"/>
    <solid android:color="#FFF" />
    <padding
        android:left="2sp"
        android:right="2sp"/>
</shape>
+6 −0
Original line number Diff line number Diff line
@@ -177,6 +177,12 @@
    <!-- Size of the view displaying the mobile signal icon in the status bar. This value should
        match the viewport height of mobile signal drawables such as ic_lte_mobiledata -->
    <dimen name="status_bar_mobile_type_size">16sp</dimen>
    <!-- Size of the view that contains the network type. Should be equal to
    status_bar_mobile_type_size + 2, to account for 1sp top and bottom padding -->
    <dimen name="status_bar_mobile_container_height">18sp</dimen>
    <!-- Corner radius for the background of the network type indicator. Should be equal to
        status_bar_mobile_container_height / 2 -->
    <dimen name="status_bar_mobile_container_corner_radius">9sp</dimen>
    <!-- Size of the view displaying the mobile roam icon in the status bar. This value should
        match the viewport size of drawable stat_sys_roaming -->
    <dimen name="status_bar_mobile_roam_size">8sp</dimen>
+6 −0
Original line number Diff line number Diff line
@@ -76,6 +76,9 @@ interface MobileIconInteractor {
    /** Observable for RAT type (network type) indicator */
    val networkTypeIconGroup: StateFlow<NetworkTypeIconModel>

    /** Whether or not to show the slice attribution */
    val showSliceAttribution: StateFlow<Boolean>

    /**
     * Provider name for this network connection. The name can be one of 3 values:
     * 1. The default network name, if one is configured
@@ -238,6 +241,9 @@ class MobileIconInteractorImpl(
                DefaultIcon(defaultMobileIconGroup.value),
            )

    override val showSliceAttribution: StateFlow<Boolean> =
        connectionRepository.hasPrioritizedNetworkCapabilities

    override val isRoaming: StateFlow<Boolean> =
        combine(
                connectionRepository.carrierNetworkChangeActive,
+56 −12
Original line number Diff line number Diff line
@@ -16,11 +16,13 @@

package com.android.systemui.statusbar.pipeline.mobile.ui.binder

import android.annotation.ColorInt
import android.content.res.ColorStateList
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.Space
import androidx.core.view.isVisible
@@ -28,10 +30,11 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.settingslib.graph.SignalDrawable
import com.android.systemui.res.R
import com.android.systemui.common.ui.binder.ContentDescriptionViewBinder
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.res.R
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
@@ -43,6 +46,11 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch

private data class Colors(
    @ColorInt val tint: Int,
    @ColorInt val contrast: Int,
)

object MobileIconBinder {
    /** Binds the view to the view-model, continuing to update the former based on the latter */
    @JvmStatic
@@ -57,6 +65,7 @@ object MobileIconBinder {
        val activityIn = view.requireViewById<ImageView>(R.id.mobile_in)
        val activityOut = view.requireViewById<ImageView>(R.id.mobile_out)
        val networkTypeView = view.requireViewById<ImageView>(R.id.mobile_type)
        val networkTypeContainer = view.requireViewById<FrameLayout>(R.id.mobile_type_container)
        val iconView = view.requireViewById<ImageView>(R.id.mobile_signal)
        val mobileDrawable = SignalDrawable(view.context).also { iconView.setImageDrawable(it) }
        val roamingView = view.requireViewById<ImageView>(R.id.mobile_roaming)
@@ -70,7 +79,13 @@ object MobileIconBinder {
        @StatusBarIconView.VisibleState
        val visibilityState: MutableStateFlow<Int> = MutableStateFlow(initialVisibilityState)

        val iconTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
        val iconTint: MutableStateFlow<Colors> =
            MutableStateFlow(
                Colors(
                    tint = DarkIconDispatcher.DEFAULT_ICON_TINT,
                    contrast = DarkIconDispatcher.DEFAULT_INVERSE_ICON_TINT
                )
            )
        val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)

        var isCollecting = false
@@ -139,7 +154,26 @@ object MobileIconBinder {
                                dataTypeId,
                            )
                            dataTypeId?.let { IconViewBinder.bind(dataTypeId, networkTypeView) }
                            networkTypeView.visibility = if (dataTypeId != null) VISIBLE else GONE
                            networkTypeContainer.visibility =
                                if (dataTypeId != null) VISIBLE else GONE
                        }
                    }

                    // Set the network type background
                    launch {
                        viewModel.networkTypeBackground.collect { background ->
                            networkTypeContainer.setBackgroundResource(background?.res ?: 0)

                            // Tint will invert when this bit changes
                            if (background?.res != null) {
                                networkTypeContainer.backgroundTintList =
                                    ColorStateList.valueOf(iconTint.value.tint)
                                networkTypeView.imageTintList =
                                    ColorStateList.valueOf(iconTint.value.contrast)
                            } else {
                                networkTypeView.imageTintList =
                                    ColorStateList.valueOf(iconTint.value.tint)
                            }
                        }
                    }

@@ -164,14 +198,24 @@ object MobileIconBinder {

                    // Set the tint
                    launch {
                        iconTint.collect { tint ->
                            val tintList = ColorStateList.valueOf(tint)
                            iconView.imageTintList = tintList
                            networkTypeView.imageTintList = tintList
                            roamingView.imageTintList = tintList
                            activityIn.imageTintList = tintList
                            activityOut.imageTintList = tintList
                            dotView.setDecorColor(tint)
                        iconTint.collect { colors ->
                            val tint = ColorStateList.valueOf(colors.tint)
                            val contrast = ColorStateList.valueOf(colors.contrast)

                            iconView.imageTintList = tint

                            // If the bg is visible, tint it and use the contrast for the fg
                            if (viewModel.networkTypeBackground.value != null) {
                                networkTypeContainer.backgroundTintList = tint
                                networkTypeView.imageTintList = contrast
                            } else {
                                networkTypeView.imageTintList = tint
                            }

                            roamingView.imageTintList = tint
                            activityIn.imageTintList = tint
                            activityOut.imageTintList = tint
                            dotView.setDecorColor(colors.tint)
                        }
                    }

@@ -197,7 +241,7 @@ object MobileIconBinder {
            }

            override fun onIconTintChanged(newTint: Int, contrastTint: Int) {
                iconTint.value = newTint
                iconTint.value = Colors(tint = newTint, contrast = contrastTint)
            }

            override fun onDecorTintChanged(newTint: Int) {
Loading