diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 1e608f5c12400a243aa85f9d5047d4bcd1c7c29e..bb01e0c3c0fb8e3a62db70248dd7b1d3a0dc3219 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -74,6 +74,9 @@ import com.android.server.am.BatteryStatsService; import com.android.server.lights.LightsManager; import com.android.server.lights.LogicalLight; +import com.android.internal.libremobileos.notification.LedValues; +import com.android.internal.libremobileos.notification.LineageBatteryLights; + import java.io.File; import java.io.FileDescriptor; import java.io.FileOutputStream; @@ -200,6 +203,8 @@ public final class BatteryService extends SystemService { private MetricsLogger mMetricsLogger; + private LineageBatteryLights mLineageBatteryLights; + public BatteryService(Context context) { super(context); @@ -271,6 +276,16 @@ public final class BatteryService extends SystemService { false, obs, UserHandle.USER_ALL); updateBatteryWarningLevelLocked(); } + } else if (phase == PHASE_BOOT_COMPLETED) { + mLineageBatteryLights = new LineageBatteryLights(mContext, + new LineageBatteryLights.LedUpdater() { + public void update() { + updateLedPulse(); + } + }); + + // Update light state now that mLineageBatteryLights has been initialized. + updateLedPulse(); } } @@ -1128,6 +1143,10 @@ public final class BatteryService extends SystemService { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } + private synchronized void updateLedPulse() { + mLed.updateLightsLocked(); + } + private final class Led { private final LogicalLight mBatteryLight; @@ -1159,29 +1178,35 @@ public final class BatteryService extends SystemService { if (mBatteryLight == null) { return; } - final int level = mHealthInfo.batteryLevel; - final int status = mHealthInfo.batteryStatus; - if (level < mLowBatteryWarningLevel) { - if (status == BatteryManager.BATTERY_STATUS_CHARGING) { - // Solid red when battery is charging - mBatteryLight.setColor(mBatteryLowARGB); - } else { - // Flash red when battery is low and not charging - mBatteryLight.setFlashing(mBatteryLowARGB, LogicalLight.LIGHT_FLASH_TIMED, - mBatteryLedOn, mBatteryLedOff); - } - } else if (status == BatteryManager.BATTERY_STATUS_CHARGING - || status == BatteryManager.BATTERY_STATUS_FULL) { - if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) { - // Solid green when full or charging and nearly full - mBatteryLight.setColor(mBatteryFullARGB); - } else { - // Solid orange when charging and halfway full - mBatteryLight.setColor(mBatteryMediumARGB); + // mHealthInfo could be null on startup (called by SettingsObserver) + if (mHealthInfo == null) { + Slog.w(TAG, "updateLightsLocked: mHealthInfo is null; skipping"); + return; + } + // mLineageBatteryLights is initialized during PHASE_BOOT_COMPLETED + // This means we don't have Lineage battery settings yet so skip. + if (mLineageBatteryLights == null) { + if (DEBUG) { + Slog.w(TAG, "updateLightsLocked: mLineageBatteryLights is not yet ready; " + + "skipping"); } - } else { - // No lights if not charging and not low + return; + } + if (!mLineageBatteryLights.isSupported()) { + return; + } + + LedValues ledValues = new LedValues(0 /* color */, mBatteryLedOn, mBatteryLedOff); + mLineageBatteryLights.calcLights(ledValues, mHealthInfo.batteryLevel, + mHealthInfo.batteryStatus, mHealthInfo.batteryLevel <= mLowBatteryWarningLevel); + + if (!ledValues.isEnabled()) { mBatteryLight.turnOff(); + } else if (ledValues.isPulsed()) { + mBatteryLight.setFlashing(ledValues.getColor(), LogicalLight.LIGHT_FLASH_TIMED, + ledValues.getOnMs(), ledValues.getOffMs()); + } else { + mBatteryLight.setColor(ledValues.getColor()); } } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index dbcea8258d7731fd52bd68b45edfacb982e91c64..6074e21a9f4d66cdc1aea07756877a95629c7374 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1,5 +1,7 @@ /* * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project + * Copyright (C) 2017 The LineageOS Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -299,6 +301,9 @@ import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.BackgroundActivityStartCallback; import com.android.server.wm.WindowManagerInternal; +import com.android.internal.libremobileos.notification.LedValues; +import com.android.internal.libremobileos.notification.LineageNotificationLights; + import libcore.io.IoUtils; import org.json.JSONException; @@ -618,6 +623,8 @@ public class NotificationManagerService extends SystemService { private InstanceIdSequence mNotificationInstanceIdSequence; private Set<String> mMsgPkgsAllowedAsConvos = new HashSet(); + private LineageNotificationLights mLineageNotificationLights; + static class Archive { final SparseArray<Boolean> mEnabled; final int mBufferSize; @@ -1532,8 +1539,11 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mNotificationLock") private void clearLightsLocked() { // light - mLights.clear(); - updateLightsLocked(); + // clear only if lockscreen is not active + if (!mLineageNotificationLights.isKeyguardLocked()) { + mLights.clear(); + updateLightsLocked(); + } } protected final BroadcastReceiver mLocaleChangeReceiver = new BroadcastReceiver() { @@ -1739,7 +1749,10 @@ public class NotificationManagerService extends SystemService { } else if (action.equals(Intent.ACTION_USER_PRESENT)) { // turn off LED when user passes through lock screen if (mNotificationLight != null) { - mNotificationLight.turnOff(); + // if lights with screen on is disabled. + if (!mLineageNotificationLights.showLightsScreenOn()) { + mNotificationLight.turnOff(); + } } } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL); @@ -2117,6 +2130,7 @@ public class NotificationManagerService extends SystemService { new Intent(ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL) .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT), UserHandle.ALL, permission.MANAGE_NOTIFICATIONS); + mLineageNotificationLights.setZenMode(mZenModeHelper.getZenMode()); synchronized (mNotificationLock) { updateInterruptionFilterLocked(); } @@ -2366,8 +2380,16 @@ public class NotificationManagerService extends SystemService { LocalServices.getService(ActivityManagerInternal.class), createToastRateLimiter()); + mLineageNotificationLights = new LineageNotificationLights(getContext(), + new LineageNotificationLights.LedUpdater() { + public void update() { + updateNotificationPulse(); + } + }); + publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL); + publishBinderService(Context.NOTIFICATION_SERVICE, mService); publishLocalService(NotificationManagerInternal.class, mInternalService); } @@ -7472,6 +7494,12 @@ public class NotificationManagerService extends SystemService { if (!mHasLight) { return false; } + // Forced on + // Used by LineageParts light picker + // eg to allow selecting battery light color when notification led is turned off. + if (isLedForcedOn(record)) { + return true; + } // user turned lights off globally if (!mNotificationPulseEnabled) { return false; @@ -7484,10 +7512,6 @@ public class NotificationManagerService extends SystemService { if (!aboveThreshold) { return false; } - // suppressed due to DND - if ((record.getSuppressedVisualEffects() & SUPPRESSED_EFFECT_LIGHTS) != 0) { - return false; - } // Suppressed because it's a silent update final Notification notification = record.getNotification(); if (record.isUpdate && (notification.flags & FLAG_ONLY_ALERT_ONCE) != 0) { @@ -7497,10 +7521,6 @@ public class NotificationManagerService extends SystemService { if (record.getSbn().isGroup() && record.getNotification().suppressAlertingDueToGrouping()) { return false; } - // not if in call - if (isInCall()) { - return false; - } // check current user if (!isNotificationForCurrentUser(record)) { return false; @@ -8942,19 +8962,43 @@ public class NotificationManagerService extends SystemService { } } - // Don't flash while we are in a call or screen is on - if (ledNotification == null || isInCall() || mScreenOn) { + NotificationRecord.Light light = ledNotification != null ? + ledNotification.getLight() : null; + if (ledNotification == null || mLineageNotificationLights == null || light == null) { + mNotificationLight.turnOff(); + return; + } + + int ledColor = light.color; + if (isLedForcedOn(ledNotification) && ledColor == 0) { + // User has requested color 0. However, lineage-sdk interprets + // color 0 as "supply a default" therefore adjust alpha to make + // the color still black but non-zero. + ledColor = 0x01000000; + } + + LedValues ledValues = new LedValues(ledColor, light.onMs, light.offMs); + mLineageNotificationLights.calcLights(ledValues, ledNotification.getSbn().getPackageName(), + ledNotification.getSbn().getNotification(), mScreenOn || isInCall(), + ledNotification.getSuppressedVisualEffects()); + + if (!ledValues.isEnabled()) { mNotificationLight.turnOff(); } else { - NotificationRecord.Light light = ledNotification.getLight(); - if (light != null && mNotificationPulseEnabled) { - // pulse repeatedly - mNotificationLight.setFlashing(light.color, LogicalLight.LIGHT_FLASH_TIMED, - light.onMs, light.offMs); + // we are using 1:0 to indicate LED should stay always on + if (ledValues.getOnMs() == 1 && ledValues.getOffMs() == 0) { + mNotificationLight.setColor(ledValues.getColor()); + } else { + mNotificationLight.setFlashing(ledValues.getColor(), + LogicalLight.LIGHT_FLASH_TIMED, ledValues.getOnMs(), ledValues.getOffMs()); } } } + private boolean isLedForcedOn(NotificationRecord nr) { + return nr != null && mLineageNotificationLights.isForcedOn(nr.getSbn().getNotification()); + } + @GuardedBy("mNotificationLock") @NonNull List<NotificationRecord> findCurrentAndSnoozedGroupNotificationsLocked(String pkg, diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index b6b54fc1901123180c9c5e13f32f352d70072742..b62ee6dc3919ec84962b172cb35f809b933742b9 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -263,8 +263,8 @@ public final class NotificationRecord { } private Light calculateLights() { - int defaultLightColor = mContext.getResources().getColor( - com.android.internal.R.color.config_defaultNotificationColor); + // Lineage lights will set the default color later + int defaultLightColor = 0; int defaultLightOn = mContext.getResources().getInteger( com.android.internal.R.integer.config_defaultNotificationLedOn); int defaultLightOff = mContext.getResources().getInteger(