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

Commit c36a6daa authored by Ioana Alexandru's avatar Ioana Alexandru
Browse files

Notif redesign: Show small icon for headless system apps

The implementation to determine if an app iss a headless system app is
the same as the one currently in Notification.java (that's currently
used by a prototype and will be removed).

Bug: 371174789
Test: tested manually for now, unit tests to be added when caching is
implemented
Flag: android.app.notifications_redesign_app_icons

Change-Id: Id93b040f05b6ecea5a41f96a3a66179ba7f58513
parent 0023b25c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.row;

import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.notification.row.icon.AppIconProviderModule;
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProviderModule;
import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor;

import dagger.Binds;
@@ -29,7 +30,7 @@ import javax.inject.Provider;
/**
 * Dagger Module containing notification row and view inflation implementations.
 */
@Module(includes = {AppIconProviderModule.class})
@Module(includes = {AppIconProviderModule.class, NotificationIconStyleProviderModule.class})
public abstract class NotificationRowModule {

    /**
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.row.icon

import android.annotation.WorkerThread
import android.app.Flags
import android.content.Context
import android.content.pm.ApplicationInfo
import android.service.notification.StatusBarNotification
import android.util.Log
import com.android.systemui.dagger.SysUISingleton
import dagger.Module
import dagger.Provides
import javax.inject.Inject
import javax.inject.Provider

/**
 * A provider used to cache and fetch information about which icon should be displayed by
 * notifications.
 */
interface NotificationIconStyleProvider {
    @WorkerThread
    fun shouldShowAppIcon(notification: StatusBarNotification, context: Context): Boolean
}

@SysUISingleton
class NotificationIconStyleProviderImpl @Inject constructor() : NotificationIconStyleProvider {
    override fun shouldShowAppIcon(notification: StatusBarNotification, context: Context): Boolean {
        val packageContext = notification.getPackageContext(context)
        return !belongsToHeadlessSystemApp(packageContext)
    }

    @WorkerThread
    private fun belongsToHeadlessSystemApp(context: Context): Boolean {
        val info = context.applicationInfo
        if (info != null) {
            if ((info.flags and ApplicationInfo.FLAG_SYSTEM) == 0) {
                // It's not a system app at all.
                return false
            } else {
                // If there's no launch intent, it's probably a headless app.
                val pm = context.packageManager
                return (pm.getLaunchIntentForPackage(info.packageName) == null)
            }
        } else {
            // If for some reason we don't have the app info, we don't know; best assume it's
            // not a system app.
            return false
        }
    }
}

class NoOpIconStyleProvider : NotificationIconStyleProvider {
    companion object {
        const val TAG = "NoOpIconStyleProvider"
    }

    override fun shouldShowAppIcon(notification: StatusBarNotification, context: Context): Boolean {
        Log.wtf(TAG, "NoOpIconStyleProvider should not be used anywhere.")
        return true
    }
}

@Module
class NotificationIconStyleProviderModule {
    @Provides
    @SysUISingleton
    fun provideImpl(
        realImpl: Provider<NotificationIconStyleProviderImpl>
    ): NotificationIconStyleProvider =
        if (Flags.notificationsRedesignAppIcons()) {
            realImpl.get()
        } else {
            NoOpIconStyleProvider()
        }
}
+5 −3
Original line number Diff line number Diff line
@@ -32,7 +32,10 @@ import javax.inject.Inject
 */
class NotificationRowIconViewInflaterFactory
@Inject
constructor(private val appIconProvider: AppIconProvider) : NotifRemoteViewsFactory {
constructor(
    private val appIconProvider: AppIconProvider,
    private val iconStyleProvider: NotificationIconStyleProvider,
) : NotifRemoteViewsFactory {
    override fun instantiate(
        row: ExpandableNotificationRow,
        @NotificationRowContentBinder.InflationFlag layoutType: Int,
@@ -48,8 +51,7 @@ constructor(private val appIconProvider: AppIconProvider) : NotifRemoteViewsFact
                    view.setIconProvider(
                        object : NotificationRowIconView.NotificationIconProvider {
                            override fun shouldShowAppIcon(): Boolean {
                                // TODO(b/371174789): implement me
                                return true
                                return iconStyleProvider.shouldShowAppIcon(row.entry.sbn, context)
                            }

                            override fun getAppIcon(): Drawable {
+5 −1
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag
import com.android.systemui.statusbar.notification.row.icon.AppIconProviderImpl
import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProviderImpl
import com.android.systemui.statusbar.notification.row.icon.NotificationRowIconViewInflaterFactory
import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger
@@ -287,7 +288,10 @@ class ExpandableNotificationRowBuilder(
            BigPictureLayoutInflaterFactory(),
            NotificationOptimizedLinearLayoutFactory(),
            { Mockito.mock(NotificationViewFlipperFactory::class.java) },
            NotificationRowIconViewInflaterFactory(AppIconProviderImpl(context)),
            NotificationRowIconViewInflaterFactory(
                AppIconProviderImpl(context),
                NotificationIconStyleProviderImpl(),
            ),
        )
    }

+21 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.row.icon

import com.android.systemui.kosmos.Kosmos

val Kosmos.notificationIconStyleProvider by Kosmos.Fixture { NotificationIconStyleProviderImpl() }