Loading packages/SystemUI/aconfig/systemui.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,13 @@ flag { bug: "375010573" } flag { name: "show_icon_in_empty_shade" namespace: "systemui" description: "Show a representative icon when there are no notifications in the shade." bug: "388472403" } flag { name: "notification_row_is_removed_fix" namespace: "systemui" Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt +116 −10 Original line number Diff line number Diff line Loading @@ -18,13 +18,18 @@ package com.android.systemui.statusbar.notification.emptyshade.ui.viewmodel import android.app.NotificationManager.Policy import android.content.res.Configuration import android.content.testableContext import android.graphics.drawable.TestStubDrawable import android.os.LocaleList import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import android.provider.Settings import android.service.notification.ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST import androidx.test.filters.SmallTest import com.android.settingslib.notification.data.repository.updateNotificationPolicy import com.android.settingslib.notification.modes.TestModeBuilder import com.android.settingslib.notification.modes.ZenMode import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository import com.android.systemui.flags.andSceneContainer Loading @@ -32,12 +37,15 @@ import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.res.R import com.android.systemui.shared.settings.data.repository.fakeSecureSettingsRepository import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.emptyshade.ui.shared.flag.ShowIconInEmptyShade import com.android.systemui.statusbar.policy.data.repository.zenModeRepository import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import java.util.Locale import kotlinx.coroutines.flow.map import org.junit.After import org.junit.Before import org.junit.Test Loading @@ -48,7 +56,15 @@ import platform.test.runner.parameterized.Parameters @RunWith(ParameterizedAndroidJunit4::class) @SmallTest class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { private val kosmos = testKosmos().apply { useUnconfinedTestDispatcher() } private val kosmos = testKosmos().apply { useUnconfinedTestDispatcher() testableContext.orCreateTestableResources.apply { addOverride(DND_DRAWABLE_ID, TestStubDrawable("dnd")) addOverride(BEDTIME_DRAWABLE_ID, TestStubDrawable("bedtime")) addOverride(THEATER_DRAWABLE_ID, TestStubDrawable("theater")) } } private val fakeConfigurationRepository = kosmos.fakeConfigurationRepository /** Backup of the current locales, to be restored at the end of the test if they are changed. */ Loading @@ -62,6 +78,10 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf().andSceneContainer() } const val DND_DRAWABLE_ID = com.android.internal.R.drawable.ic_zen_mode_type_special_dnd const val BEDTIME_DRAWABLE_ID = com.android.internal.R.drawable.ic_zen_mode_type_driving const val THEATER_DRAWABLE_ID = com.android.internal.R.drawable.ic_zen_mode_type_theater } init { Loading Loading @@ -123,6 +143,7 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { } @Test @DisableFlags(ShowIconInEmptyShade.FLAG_NAME) fun text_changesWhenLocaleChanges() = kosmos.runTest { val text by collectLastValue(underTest.text) Loading @@ -141,21 +162,41 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { } @Test @EnableFlags(ShowIconInEmptyShade.FLAG_NAME) fun messageString_changesWhenLocaleChanges() = kosmos.runTest { val text by collectLastValue(underTest.message.map { it.message }) zenModeRepository.updateMode(ZenMode.MANUAL_DND_MODE_ID) { TestModeBuilder(it) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() } assertThat(text).isEqualTo("Notifications paused by Do Not Disturb") updateLocales(LocaleList(Locale.GERMAN)) assertThat(text).isEqualTo("Benachrichtigungen durch Do Not Disturb pausiert") // Make sure we restore the original locales updateLocales(originalLocales) } @Test @DisableFlags(ShowIconInEmptyShade.FLAG_NAME) fun text_reflectsModesHidingNotifications() = kosmos.runTest { val text by collectLastValue(underTest.text) assertThat(text).isEqualTo("No notifications") zenModeRepository.addMode( TestModeBuilder() .setId("Do not disturb") .setName("Do not disturb") zenModeRepository.updateMode(ZenMode.MANUAL_DND_MODE_ID) { TestModeBuilder(it) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(text).isEqualTo("Notifications paused by Do not disturb") } assertThat(text).isEqualTo("Notifications paused by Do Not Disturb") zenModeRepository.addMode( TestModeBuilder() Loading @@ -165,7 +206,7 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(text).isEqualTo("Notifications paused by Do not disturb and one other mode") assertThat(text).isEqualTo("Notifications paused by Do Not Disturb and one other mode") zenModeRepository.addMode( TestModeBuilder() Loading @@ -175,14 +216,68 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(text).isEqualTo("Notifications paused by Do not disturb and 2 other modes") assertThat(text).isEqualTo("Notifications paused by Do Not Disturb and 2 other modes") zenModeRepository.deactivateMode("Do not disturb") zenModeRepository.deactivateMode(ZenMode.MANUAL_DND_MODE_ID) zenModeRepository.deactivateMode("Work") assertThat(text).isEqualTo("Notifications paused by Gym") } @Test @EnableFlags(ShowIconInEmptyShade.FLAG_NAME) fun message_reflectsModesHidingNotifications() = kosmos.runTest { val message by collectLastValue(underTest.message) assertThat(message?.message).isEqualTo("You're all caught up!") assertThat(message?.icon?.resId).isEqualTo(R.drawable.ic_trophy) zenModeRepository.updateMode(ZenMode.MANUAL_DND_MODE_ID) { TestModeBuilder(it) .setIconResId(DND_DRAWABLE_ID) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() } assertThat(message?.message).isEqualTo("Notifications paused by Do Not Disturb") assertThat(message?.icon?.resId).isEqualTo(DND_DRAWABLE_ID) zenModeRepository.addMode( TestModeBuilder() .setPackage("android") .setId("Bedtime") .setName("Bedtime") .setIconResId(BEDTIME_DRAWABLE_ID) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(message?.message) .isEqualTo("Notifications paused by Do Not Disturb and one other mode") assertThat(message?.icon?.resId).isEqualTo(DND_DRAWABLE_ID) zenModeRepository.addMode( TestModeBuilder() .setPackage("android") .setId("Theater") .setName("Theater") .setIconResId(THEATER_DRAWABLE_ID) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(message?.message) .isEqualTo("Notifications paused by Do Not Disturb and 2 other modes") assertThat(message?.icon?.resId).isEqualTo(DND_DRAWABLE_ID) zenModeRepository.deactivateMode(ZenMode.MANUAL_DND_MODE_ID) zenModeRepository.deactivateMode("Bedtime") assertThat(message?.message).isEqualTo("Notifications paused by Theater") assertThat(message?.icon?.resId).isEqualTo(THEATER_DRAWABLE_ID) } @Test @DisableFlags(ShowIconInEmptyShade.FLAG_NAME) fun footer_isVisibleWhenSeenNotifsAreFilteredOut() = kosmos.runTest { val footerVisible by collectLastValue(underTest.footer.isVisible) Loading @@ -194,6 +289,17 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { assertThat(footerVisible).isTrue() } @Test @EnableFlags(ShowIconInEmptyShade.FLAG_NAME) fun message_reflectsFilteredOutSeenNotifs() = kosmos.runTest { val message by collectLastValue(underTest.message) activeNotificationListRepository.hasFilteredOutSeenNotifications.value = true assertThat(message?.message).isEqualTo("Unlock to see older notifications") assertThat(message?.icon?.resId).isEqualTo(R.drawable.ic_friction_lock_closed) } @Test fun onClick_whenHistoryDisabled_leadsToSettingsPage() = kosmos.runTest { Loading packages/SystemUI/res/drawable/ic_trophy.xml 0 → 100644 +10 −0 Original line number Diff line number Diff line <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960" android:tint="?attr/colorControlNormal"> <path android:fillColor="@android:color/white" android:pathData="M280,840L280,760L440,760L440,636Q391,625 352.5,594.5Q314,564 296,518Q221,509 170.5,452.5Q120,396 120,320L120,280Q120,247 143.5,223.5Q167,200 200,200L280,200L280,120L680,120L680,200L760,200Q793,200 816.5,223.5Q840,247 840,280L840,320Q840,396 789.5,452.5Q739,509 664,518Q646,564 607.5,594.5Q569,625 520,636L520,760L680,760L680,840L280,840ZM280,432L280,280L200,280L200,320Q200,358 222,388.5Q244,419 280,432ZM680,432Q716,419 738,388.5Q760,358 760,320L760,280L680,280L680,432Z"/> </vector> packages/SystemUI/res/layout/empty_shade_view.xml 0 → 100644 +55 −0 Original line number Diff line number Diff line <!-- ~ Copyright (C) 2025 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 --> <!-- This layout replaces status_bar_no_notifications when ShowIconInEmptyShade is turned on. --> <!-- Extends FrameLayout --> <com.android.systemui.statusbar.notification.emptyshade.ui.view.EmptyShadeIconView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone"> <LinearLayout android:id="@id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:orientation="vertical" android:paddingVertical="@dimen/empty_shade_vertical_padding" android:paddingHorizontal="@dimen/empty_shade_horizontal_padding"> <ImageView android:id="@id/icon" android:layout_width="@dimen/empty_shade_icon_size" android:layout_height="@dimen/empty_shade_icon_size" android:layout_marginBottom="@dimen/empty_shade_icon_bottom_margin" android:scaleType="fitCenter" app:tint="@androidprv:color/materialColorOnSurface" android:importantForAccessibility="no" android:src="@drawable/ic_trophy"></ImageView> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/empty_shade_text" android:textAppearance="@style/TextAppearance.NotificationShadeText" /> </LinearLayout> </com.android.systemui.statusbar.notification.emptyshade.ui.view.EmptyShadeIconView> packages/SystemUI/res/values/dimens.xml +8 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,14 @@ <dimen name="notifications_unseen_footer_icon_size">16dp</dimen> <!-- The size of the icon shown in the shade when there are no notifications --> <dimen name="empty_shade_icon_size">32dp</dimen> <!-- The spacing between the icon and the text shown in the shade when there are no notifications. --> <dimen name="empty_shade_icon_bottom_margin">16dp</dimen> <dimen name="empty_shade_vertical_padding">32dp</dimen> <dimen name="empty_shade_horizontal_padding">16dp</dimen> <!-- Height of the status bar header bar when on Keyguard --> <dimen name="status_bar_header_height_keyguard">@dimen/status_bar_height</dimen> Loading Loading
packages/SystemUI/aconfig/systemui.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,13 @@ flag { bug: "375010573" } flag { name: "show_icon_in_empty_shade" namespace: "systemui" description: "Show a representative icon when there are no notifications in the shade." bug: "388472403" } flag { name: "notification_row_is_removed_fix" namespace: "systemui" Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt +116 −10 Original line number Diff line number Diff line Loading @@ -18,13 +18,18 @@ package com.android.systemui.statusbar.notification.emptyshade.ui.viewmodel import android.app.NotificationManager.Policy import android.content.res.Configuration import android.content.testableContext import android.graphics.drawable.TestStubDrawable import android.os.LocaleList import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.platform.test.flag.junit.FlagsParameterization import android.provider.Settings import android.service.notification.ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST import androidx.test.filters.SmallTest import com.android.settingslib.notification.data.repository.updateNotificationPolicy import com.android.settingslib.notification.modes.TestModeBuilder import com.android.settingslib.notification.modes.ZenMode import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository import com.android.systemui.flags.andSceneContainer Loading @@ -32,12 +37,15 @@ import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.useUnconfinedTestDispatcher import com.android.systemui.res.R import com.android.systemui.shared.settings.data.repository.fakeSecureSettingsRepository import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.emptyshade.ui.shared.flag.ShowIconInEmptyShade import com.android.systemui.statusbar.policy.data.repository.zenModeRepository import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import java.util.Locale import kotlinx.coroutines.flow.map import org.junit.After import org.junit.Before import org.junit.Test Loading @@ -48,7 +56,15 @@ import platform.test.runner.parameterized.Parameters @RunWith(ParameterizedAndroidJunit4::class) @SmallTest class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { private val kosmos = testKosmos().apply { useUnconfinedTestDispatcher() } private val kosmos = testKosmos().apply { useUnconfinedTestDispatcher() testableContext.orCreateTestableResources.apply { addOverride(DND_DRAWABLE_ID, TestStubDrawable("dnd")) addOverride(BEDTIME_DRAWABLE_ID, TestStubDrawable("bedtime")) addOverride(THEATER_DRAWABLE_ID, TestStubDrawable("theater")) } } private val fakeConfigurationRepository = kosmos.fakeConfigurationRepository /** Backup of the current locales, to be restored at the end of the test if they are changed. */ Loading @@ -62,6 +78,10 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { fun getParams(): List<FlagsParameterization> { return FlagsParameterization.allCombinationsOf().andSceneContainer() } const val DND_DRAWABLE_ID = com.android.internal.R.drawable.ic_zen_mode_type_special_dnd const val BEDTIME_DRAWABLE_ID = com.android.internal.R.drawable.ic_zen_mode_type_driving const val THEATER_DRAWABLE_ID = com.android.internal.R.drawable.ic_zen_mode_type_theater } init { Loading Loading @@ -123,6 +143,7 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { } @Test @DisableFlags(ShowIconInEmptyShade.FLAG_NAME) fun text_changesWhenLocaleChanges() = kosmos.runTest { val text by collectLastValue(underTest.text) Loading @@ -141,21 +162,41 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { } @Test @EnableFlags(ShowIconInEmptyShade.FLAG_NAME) fun messageString_changesWhenLocaleChanges() = kosmos.runTest { val text by collectLastValue(underTest.message.map { it.message }) zenModeRepository.updateMode(ZenMode.MANUAL_DND_MODE_ID) { TestModeBuilder(it) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() } assertThat(text).isEqualTo("Notifications paused by Do Not Disturb") updateLocales(LocaleList(Locale.GERMAN)) assertThat(text).isEqualTo("Benachrichtigungen durch Do Not Disturb pausiert") // Make sure we restore the original locales updateLocales(originalLocales) } @Test @DisableFlags(ShowIconInEmptyShade.FLAG_NAME) fun text_reflectsModesHidingNotifications() = kosmos.runTest { val text by collectLastValue(underTest.text) assertThat(text).isEqualTo("No notifications") zenModeRepository.addMode( TestModeBuilder() .setId("Do not disturb") .setName("Do not disturb") zenModeRepository.updateMode(ZenMode.MANUAL_DND_MODE_ID) { TestModeBuilder(it) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(text).isEqualTo("Notifications paused by Do not disturb") } assertThat(text).isEqualTo("Notifications paused by Do Not Disturb") zenModeRepository.addMode( TestModeBuilder() Loading @@ -165,7 +206,7 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(text).isEqualTo("Notifications paused by Do not disturb and one other mode") assertThat(text).isEqualTo("Notifications paused by Do Not Disturb and one other mode") zenModeRepository.addMode( TestModeBuilder() Loading @@ -175,14 +216,68 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(text).isEqualTo("Notifications paused by Do not disturb and 2 other modes") assertThat(text).isEqualTo("Notifications paused by Do Not Disturb and 2 other modes") zenModeRepository.deactivateMode("Do not disturb") zenModeRepository.deactivateMode(ZenMode.MANUAL_DND_MODE_ID) zenModeRepository.deactivateMode("Work") assertThat(text).isEqualTo("Notifications paused by Gym") } @Test @EnableFlags(ShowIconInEmptyShade.FLAG_NAME) fun message_reflectsModesHidingNotifications() = kosmos.runTest { val message by collectLastValue(underTest.message) assertThat(message?.message).isEqualTo("You're all caught up!") assertThat(message?.icon?.resId).isEqualTo(R.drawable.ic_trophy) zenModeRepository.updateMode(ZenMode.MANUAL_DND_MODE_ID) { TestModeBuilder(it) .setIconResId(DND_DRAWABLE_ID) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() } assertThat(message?.message).isEqualTo("Notifications paused by Do Not Disturb") assertThat(message?.icon?.resId).isEqualTo(DND_DRAWABLE_ID) zenModeRepository.addMode( TestModeBuilder() .setPackage("android") .setId("Bedtime") .setName("Bedtime") .setIconResId(BEDTIME_DRAWABLE_ID) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(message?.message) .isEqualTo("Notifications paused by Do Not Disturb and one other mode") assertThat(message?.icon?.resId).isEqualTo(DND_DRAWABLE_ID) zenModeRepository.addMode( TestModeBuilder() .setPackage("android") .setId("Theater") .setName("Theater") .setIconResId(THEATER_DRAWABLE_ID) .setActive(true) .setVisualEffect(VISUAL_EFFECT_NOTIFICATION_LIST, /* allowed= */ false) .build() ) assertThat(message?.message) .isEqualTo("Notifications paused by Do Not Disturb and 2 other modes") assertThat(message?.icon?.resId).isEqualTo(DND_DRAWABLE_ID) zenModeRepository.deactivateMode(ZenMode.MANUAL_DND_MODE_ID) zenModeRepository.deactivateMode("Bedtime") assertThat(message?.message).isEqualTo("Notifications paused by Theater") assertThat(message?.icon?.resId).isEqualTo(THEATER_DRAWABLE_ID) } @Test @DisableFlags(ShowIconInEmptyShade.FLAG_NAME) fun footer_isVisibleWhenSeenNotifsAreFilteredOut() = kosmos.runTest { val footerVisible by collectLastValue(underTest.footer.isVisible) Loading @@ -194,6 +289,17 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { assertThat(footerVisible).isTrue() } @Test @EnableFlags(ShowIconInEmptyShade.FLAG_NAME) fun message_reflectsFilteredOutSeenNotifs() = kosmos.runTest { val message by collectLastValue(underTest.message) activeNotificationListRepository.hasFilteredOutSeenNotifications.value = true assertThat(message?.message).isEqualTo("Unlock to see older notifications") assertThat(message?.icon?.resId).isEqualTo(R.drawable.ic_friction_lock_closed) } @Test fun onClick_whenHistoryDisabled_leadsToSettingsPage() = kosmos.runTest { Loading
packages/SystemUI/res/drawable/ic_trophy.xml 0 → 100644 +10 −0 Original line number Diff line number Diff line <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960" android:tint="?attr/colorControlNormal"> <path android:fillColor="@android:color/white" android:pathData="M280,840L280,760L440,760L440,636Q391,625 352.5,594.5Q314,564 296,518Q221,509 170.5,452.5Q120,396 120,320L120,280Q120,247 143.5,223.5Q167,200 200,200L280,200L280,120L680,120L680,200L760,200Q793,200 816.5,223.5Q840,247 840,280L840,320Q840,396 789.5,452.5Q739,509 664,518Q646,564 607.5,594.5Q569,625 520,636L520,760L680,760L680,840L280,840ZM280,432L280,280L200,280L200,320Q200,358 222,388.5Q244,419 280,432ZM680,432Q716,419 738,388.5Q760,358 760,320L760,280L680,280L680,432Z"/> </vector>
packages/SystemUI/res/layout/empty_shade_view.xml 0 → 100644 +55 −0 Original line number Diff line number Diff line <!-- ~ Copyright (C) 2025 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 --> <!-- This layout replaces status_bar_no_notifications when ShowIconInEmptyShade is turned on. --> <!-- Extends FrameLayout --> <com.android.systemui.statusbar.notification.emptyshade.ui.view.EmptyShadeIconView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone"> <LinearLayout android:id="@id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:orientation="vertical" android:paddingVertical="@dimen/empty_shade_vertical_padding" android:paddingHorizontal="@dimen/empty_shade_horizontal_padding"> <ImageView android:id="@id/icon" android:layout_width="@dimen/empty_shade_icon_size" android:layout_height="@dimen/empty_shade_icon_size" android:layout_marginBottom="@dimen/empty_shade_icon_bottom_margin" android:scaleType="fitCenter" app:tint="@androidprv:color/materialColorOnSurface" android:importantForAccessibility="no" android:src="@drawable/ic_trophy"></ImageView> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/empty_shade_text" android:textAppearance="@style/TextAppearance.NotificationShadeText" /> </LinearLayout> </com.android.systemui.statusbar.notification.emptyshade.ui.view.EmptyShadeIconView>
packages/SystemUI/res/values/dimens.xml +8 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,14 @@ <dimen name="notifications_unseen_footer_icon_size">16dp</dimen> <!-- The size of the icon shown in the shade when there are no notifications --> <dimen name="empty_shade_icon_size">32dp</dimen> <!-- The spacing between the icon and the text shown in the shade when there are no notifications. --> <dimen name="empty_shade_icon_bottom_margin">16dp</dimen> <dimen name="empty_shade_vertical_padding">32dp</dimen> <dimen name="empty_shade_horizontal_padding">16dp</dimen> <!-- Height of the status bar header bar when on Keyguard --> <dimen name="status_bar_header_height_keyguard">@dimen/status_bar_height</dimen> Loading