• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.statusbar.notification.collection
18 
19 import android.app.Notification
20 import android.app.NotificationChannel
21 import android.app.NotificationManager.IMPORTANCE_DEFAULT
22 import android.app.NotificationManager.IMPORTANCE_LOW
23 import android.app.PendingIntent
24 import android.app.Person
25 import android.content.Intent
26 import android.content.applicationContext
27 import android.graphics.Bitmap
28 import android.graphics.drawable.Icon
29 import com.android.systemui.activity.EmptyTestActivity
30 import com.android.systemui.kosmos.Kosmos
31 import com.android.systemui.res.R
32 import com.android.systemui.statusbar.notification.icon.IconPack
33 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.PeopleNotificationType
34 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON
35 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
36 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
37 import com.android.systemui.statusbar.notification.promoted.setPromotedContent
38 import org.mockito.kotlin.mock
39 
setIconPackWithMockIconViewsnull40 fun Kosmos.setIconPackWithMockIconViews(entry: NotificationEntry) {
41     entry.icons =
42         IconPack.buildPack(
43             /* statusBarIcon = */ mock(),
44             /* statusBarChipIcon = */ mock(),
45             /* shelfIcon = */ mock(),
46             /* aodIcon = */ mock(),
47             /* source = */ null,
48         )
49 }
50 
buildPromotedOngoingEntrynull51 fun Kosmos.buildPromotedOngoingEntry(
52     block: NotificationEntryBuilder.() -> Unit = {}
53 ): NotificationEntry =
54     buildNotificationEntry(tag = "ron", promoted = true, style = null, block = block)
55 
buildOngoingCallEntrynull56 fun Kosmos.buildOngoingCallEntry(
57     promoted: Boolean = false,
58     block: NotificationEntryBuilder.() -> Unit = {},
59 ): NotificationEntry =
60     buildNotificationEntry(
61         tag = "call",
62         promoted = promoted,
63         style = makeOngoingCallStyle(),
64         block = block,
65     )
66 
buildNotificationEntrynull67 fun Kosmos.buildNotificationEntry(
68     tag: String? = null,
69     promoted: Boolean = false,
70     style: Notification.Style? = null,
71     block: NotificationEntryBuilder.() -> Unit = {},
72 ): NotificationEntry =
73     NotificationEntryBuilder()
<lambda>null74         .apply {
75             setTag(tag)
76             setFlag(applicationContext, Notification.FLAG_PROMOTED_ONGOING, promoted)
77             modifyNotification(applicationContext)
78                 .setSmallIcon(Icon.createWithContentUri("content://null"))
79                 .setStyle(style)
80         }
81         .apply(block)
82         .build()
<lambda>null83         .also {
84             setIconPackWithMockIconViews(it)
85             if (promoted) setPromotedContent(it)
86         }
87 
makeOngoingCallStylenull88 private fun Kosmos.makeOngoingCallStyle(): Notification.CallStyle {
89     val pendingIntent =
90         PendingIntent.getBroadcast(
91             applicationContext,
92             0,
93             Intent("action"),
94             PendingIntent.FLAG_IMMUTABLE,
95         )
96     val person = Person.Builder().setName("person").build()
97     return Notification.CallStyle.forOngoingCall(person, pendingIntent)
98 }
99 
makeMessagingStyleNotificationnull100 private fun Kosmos.makeMessagingStyleNotification(): Notification.Builder {
101     val personIcon = Icon.createWithBitmap(Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888))
102     val person = Person.Builder().setIcon(personIcon).setName("Person").build()
103     val message = Notification.MessagingStyle.Message("Message!", 4323, person)
104     val bubbleIntent =
105         PendingIntent.getActivity(
106             applicationContext,
107             0,
108             Intent(applicationContext, EmptyTestActivity::class.java),
109             PendingIntent.FLAG_MUTABLE,
110         )
111 
112     return Notification.Builder(applicationContext, "channelId")
113         .setSmallIcon(R.drawable.ic_person)
114         .setContentTitle("Title")
115         .setContentText("Text")
116         .setStyle(Notification.MessagingStyle(person).addMessage(message))
117         .setBubbleMetadata(
118             Notification.BubbleMetadata.Builder(
119                     bubbleIntent,
120                     Icon.createWithResource(applicationContext, R.drawable.android),
121                 )
122                 .setDeleteIntent(mock<PendingIntent>())
123                 .setDesiredHeight(314)
124                 .setAutoExpandBubble(false)
125                 .build()
126         )
127 }
128 
makeEntryOfPeopleTypenull129 fun Kosmos.makeEntryOfPeopleType(@PeopleNotificationType type: Int): NotificationEntryBuilder {
130     val channel = NotificationChannel("messages", "messages", IMPORTANCE_DEFAULT)
131     channel.isImportantConversation = (type == TYPE_IMPORTANT_PERSON)
132     channel.setConversationId("parent", "convo")
133 
134     val entry =
135         NotificationEntryBuilder().apply {
136             updateRanking {
137                 it.setIsConversation(type != TYPE_NON_PERSON)
138                 it.setShortcutInfo(if (type >= TYPE_FULL_PERSON) mock() else null)
139                 it.setChannel(channel)
140             }
141             setNotification(makeMessagingStyleNotification().build())
142         }
143     return entry
144 }
145 
Kosmosnull146 fun Kosmos.makeClassifiedConversation(channelId: String): NotificationEntry {
147     val channel = NotificationChannel(channelId, channelId, IMPORTANCE_LOW)
148     val entry =
149         NotificationEntryBuilder()
150             .updateRanking {
151                 it.setIsConversation(true)
152                 it.setShortcutInfo(mock())
153                 it.setChannel(channel)
154             }
155             .build()
156     return entry
157 }