From 33086de92a6d1a06e0203ba17de6fe74f5d7a413 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Thu, 24 Sep 2015 11:27:59 -0700 Subject: [PATCH] lights: Automatically generate an LED color for notifications * When an app doesn't specify a color for the LED, as is the usual case, we currently just show the default color. This is boring. It's also a pain in the ass to manually map all your apps to colors. * Use our new helpers to generate this color based on the application's icon color. Keep a cache to avoid wasting cycles. Change-Id: I7288e52499819a6a6c75ed9d9ba7cfa1b13c5669 nms: Only generate LED colors if the device has a multicolored LED * Check the overlay value before doing any of this stuff. Change-Id: Iedfceba6bfc86b2761d8af57ecab51026bfa4c19 --- .../notification/NotificationManagerService.java | 54 +++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 2f1ffa1a7bfd..a15d7b154870 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -80,6 +80,7 @@ import android.content.pm.ParceledListSlice; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; +import android.graphics.drawable.Drawable; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioManagerInternal; @@ -147,6 +148,7 @@ import com.android.server.vr.VrManagerInternal; import com.android.server.notification.ManagedServices.UserProfiles; import cyanogenmod.providers.CMSettings; +import cyanogenmod.util.ColorUtils; import cyanogenmod.providers.CMSettings; import libcore.io.IoUtils; @@ -262,6 +264,8 @@ public class NotificationManagerService extends SystemService { private boolean mMultipleNotificationLeds; private boolean mMultipleLedsEnabledSetting = false; + private boolean mAutoGenerateNotificationColor = true; + private boolean mScreenOnEnabled = false; private boolean mScreenOnDefault = false; @@ -286,6 +290,8 @@ public class NotificationManagerService extends SystemService { private boolean mNotificationPulseEnabled; private ArrayMap mNotificationPulseCustomLedValues; private Map mPackageNameMappings; + private final ArrayMap mGeneratedPackageLedColors = + new ArrayMap(); // for checking lockscreen status private KeyguardManager mKeyguardManager; @@ -324,6 +330,8 @@ public class NotificationManagerService extends SystemService { private ConditionProviders mConditionProviders; private NotificationUsageStats mUsageStats; + private boolean mMultiColorNotificationLed; + private static final int MY_UID = Process.myUid(); private static final int MY_PID = Process.myPid(); private RankingHandler mRankingHandler; @@ -892,6 +900,9 @@ public class NotificationManagerService extends SystemService { resolver.registerContentObserver(CMSettings.System.getUriFor( CMSettings.System.NOTIFICATION_LIGHT_SCREEN_ON), false, this, UserHandle.USER_ALL); + resolver.registerContentObserver(CMSettings.System.getUriFor( + CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO), false, + this, UserHandle.USER_ALL); if (mAdjustableNotificationLedBrightness) { resolver.registerContentObserver(CMSettings.System.getUriFor( CMSettings.System.NOTIFICATION_LIGHT_BRIGHTNESS_LEVEL), @@ -916,6 +927,11 @@ public class NotificationManagerService extends SystemService { mNotificationPulseEnabled = Settings.System.getIntForUser(resolver, Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT) != 0; + // Automatically pick a color for LED if not set + mAutoGenerateNotificationColor = CMSettings.System.getIntForUser(resolver, + CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO, + 1, UserHandle.USER_CURRENT) != 0; + // LED default color mDefaultNotificationColor = CMSettings.System.getIntForUser(resolver, CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_COLOR, @@ -931,6 +947,9 @@ public class NotificationManagerService extends SystemService { CMSettings.System.NOTIFICATION_LIGHT_PULSE_DEFAULT_LED_OFF, mDefaultNotificationLedOff, UserHandle.USER_CURRENT); + // LED generated notification colors + mGeneratedPackageLedColors.clear(); + // LED custom notification colors mNotificationPulseCustomLedValues.clear(); if (CMSettings.System.getIntForUser(resolver, @@ -1104,6 +1123,9 @@ public class NotificationManagerService extends SystemService { mDefaultNotificationLedOff = resources.getInteger( R.integer.config_defaultNotificationLedOff); + mMultiColorNotificationLed = resources.getBoolean( + R.bool.config_multiColorNotificationLed); + mNotificationPulseCustomLedValues = new ArrayMap(); mPackageNameMappings = new ArrayMap(); @@ -3747,7 +3769,7 @@ public class NotificationManagerService extends SystemService { ledOnMS = ledValues.onMS >= 0 ? ledValues.onMS : mDefaultNotificationLedOn; ledOffMS = ledValues.offMS >= 0 ? ledValues.offMS : mDefaultNotificationLedOff; } else if ((ledno.defaults & Notification.DEFAULT_LIGHTS) != 0) { - ledARGB = mDefaultNotificationColor; + ledARGB = generateLedColorForNotification(ledNotification); ledOnMS = mDefaultNotificationLedOn; ledOffMS = mDefaultNotificationLedOff; } else { @@ -3809,6 +3831,36 @@ public class NotificationManagerService extends SystemService { return mNotificationPulseCustomLedValues.get(mapPackage(packageName)); } + private int generateLedColorForNotification(NotificationRecord ledNotification) { + if (!mAutoGenerateNotificationColor) { + return mDefaultNotificationColor; + } + if (!mMultiColorNotificationLed) { + return mDefaultNotificationColor; + } + final String packageName = ledNotification.sbn.getPackageName(); + final String mapping = mapPackage(packageName); + int color = mDefaultNotificationColor; + + if (mGeneratedPackageLedColors.containsKey(mapping)) { + return mGeneratedPackageLedColors.get(mapping); + } + + PackageManager pm = getContext().getPackageManager(); + Drawable icon; + try { + icon = pm.getApplicationIcon(mapping); + } catch (NameNotFoundException e) { + Slog.e(TAG, e.getMessage(), e); + return color; + } + + color = ColorUtils.generateAlertColorFromDrawable(icon); + mGeneratedPackageLedColors.put(mapping, color); + + return color; + } + private String mapPackage(String pkg) { if (!mPackageNameMappings.containsKey(pkg)) { return pkg; -- 2.11.0