From d38ce5064c373bd8e022a47401737abb5f18f1df Mon Sep 17 00:00:00 2001 From: Sam Mortimer Date: Sun, 22 Oct 2017 14:43:46 -0700 Subject: [PATCH] lineage-sdk internal: Add LineageBatteryLights Migrate frameworks/base lineage feature code handling to lineage-sdk. *) Settings observation and most lineage lights feature specific code has been moved to the lineage-sdk. *) Battery frameworks services call out to the sdk to allow our features to make changes to lights values. Based on the commits: Author: DvTonder Author: Ricardo Cerqueira Date: Mon Nov 4 00:57:51 2013 +0000 Framework: Port CM9 features to CM10 Change-Id: Ibd63116df90b06f6ce6adb8a0343059bbb999bfb Author: Pawit Pornkitprasan Date: Sun Dec 8 15:24:41 2013 +0700 BatteryService: fix FC on boot until battery stat is present updateLightsLocked() can be called from CM's added SettingsObserver when battery stat is not present, causing an FC and a loop until battery stat is present. Change-Id: Ic4438fe50e98f1aa05ae1d0d26240bf9410fd92f Author: Sam Mortimer Date: Tue Dec 31 16:22:05 2013 -0800 [2/2] Framework: instant led test Adds support a new notification extra boolean EXTRA_FORCE_SHOW_LIGHTS. Used by settings notification light picker to force lights on when the screen is on. Change-Id: If0a42d32b28fe8c02ef5f7dd148db7eb478fac17 Author: Michael Bestas Date: Mon Aug 18 04:56:28 2014 +0300 Add support for single color notification LED (1/2) Change-Id: I367af77036da9e87c6dd0df552ce4c56d945a44d Author: Danesh M Date: Thu, 12 Nov 2015 10:52:11 -0800 Framework : Move System settings to CMSettings Change-Id: I4e9fb06db7b9ba05e4a7bbe11916bb2271af4727 Author: Adnan Begovic Date: Mon, 9 Nov 2015 16:26:00 -0800 fw: Move battery light settings to CMSettings. Change-Id: I28e60473356b2a9af152df82d34ad7abc9918682 Author: Steve Kondik Date: Thu Sep 24 11:27:59 2015 -0700 lights: Automatically generate an LED color for notifications 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 Change-Id: I7288e52499819a6a6c75ed9d9ba7cfa1b13c5669 Author: Adrian DC Date: Sat Oct 14 23:08:47 2017 +0200 fw: Rebrand to LineageOS and cleanup for Android Oreo Change-Id: I21d424433bb52a17eea7974c4ea29a3a16fe1be5 Author: AdrianDC Date: Sat Jul 18 12:20:51 2015 +0200 Lights with Screen On [1/2]: Optional allowment of lights Change-Id: I2071147d8ddab80ba0e1e7310e785ac3e03b3c7c Lights with screen on: Don't disable leds after the lockscreen Change-Id: If8f5b867a34be09fb061bb7ad040b16730f4e263 Framework : Move System settings to CMSettings Change-Id: I4e9fb06db7b9ba05e4a7bbe11916bb2271af4727 fw: Rebrand to LineageOS and port for Android Oreo Change-Id: I65cfeb659fe516ef43aa84b1c6d2eb6876df202a Change-Id: If8f5b867a34be09fb061bb7ad040b16730f4e263 Author: Michael W Date: Mon Oct 9 22:04:00 2017 +0200 Core: Battery warning levels are inclusive, not exclusive Change-Id: Ib35b154b6117f7e26b4a3a5aee9254dda3adda12 Author: Adrian DC Date: Sat Oct 14 23:08:47 2017 +0200 fw: Rebrand to LineageOS and cleanup for Android Oreo Change-Id: I845f866891386aee808a4e7e80f4ab7c3ad48830 Change-Id: I13fcb1e16756a8008d0850050e0b09ab0b92a56f --- .../notification/LineageBatteryLights.java | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 sdk/src/java/org/lineageos/internal/notification/LineageBatteryLights.java diff --git a/sdk/src/java/org/lineageos/internal/notification/LineageBatteryLights.java b/sdk/src/java/org/lineageos/internal/notification/LineageBatteryLights.java new file mode 100644 index 00000000..33ca855e --- /dev/null +++ b/sdk/src/java/org/lineageos/internal/notification/LineageBatteryLights.java @@ -0,0 +1,187 @@ +/** + * 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. + * 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 org.lineageos.internal.notification; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Resources; +import android.database.ContentObserver; +import android.os.BatteryManager; +import android.os.Handler; +import android.os.UserHandle; +import android.util.Slog; + +import lineageos.providers.LineageSettings; + +import org.lineageos.internal.notification.LedValues; +import org.lineageos.internal.notification.LightsCapabilities; + +public final class LineageBatteryLights { + private final String TAG = "LineageBatteryLights"; + private final boolean DEBUG = false; + + // Battery light capabilities. + private final boolean mMultiColorLed; + private final boolean mUseSegmentedBatteryLed; + + // Battery light intended operational state. + private boolean mLightEnabled = false; // Disable until observer is started + private boolean mLedPulseEnabled; + private int mBatteryLowARGB; + private int mBatteryMediumARGB; + private int mBatteryFullARGB; + + private final Context mContext; + + public interface LedUpdater { + public void update(); + } + private final LedUpdater mLedUpdater; + + public LineageBatteryLights(Context context, LedUpdater ledUpdater) { + mContext = context; + mLedUpdater = ledUpdater; + + // Does the device support changing battery LED colors? + mMultiColorLed = LightsCapabilities.supports( + mContext, LightsCapabilities.LIGHTS_RGB_BATTERY_LED); + + // Does the device have segmented battery LED support? In this case, we send the level + // in the alpha channel of the color and let the HAL sort it out. + mUseSegmentedBatteryLed = LightsCapabilities.supports( + mContext, LightsCapabilities.LIGHTS_SEGMENTED_BATTERY_LED); + + SettingsObserver observer = new SettingsObserver(new Handler()); + observer.observe(); + } + + public void calcLights(LedValues ledValues, int level, int status, boolean low) { + if (DEBUG) { + Slog.i(TAG, "calcLights input: ledValues={ " + ledValues + " } level=" + + level + " status=" + status + " low=" + low); + } + // The only meaningful ledValues values received by frameworks BatteryService + // are the pulse times (for low battery). Explicitly set enabled state and + // color to ensure that we arrive at a deterministic outcome. + ledValues.setEnabled(false); + ledValues.setColor(0); + + if (!mLightEnabled) { + return; + } + + ledValues.setBrightness(mUseSegmentedBatteryLed ? + level : LedValues.LIGHT_BRIGHTNESS_MAXIMUM); + + if (low) { + if (status == BatteryManager.BATTERY_STATUS_CHARGING) { + // Battery is charging and low. + ledValues.setColor(mBatteryLowARGB); + ledValues.setSolid(); + } else if (mLedPulseEnabled) { + // Battery is low, not charging and pulse is enabled + // (pulsing values are set by frameworks BatteryService). + ledValues.setColor(mBatteryLowARGB); + } + } else if (status == BatteryManager.BATTERY_STATUS_CHARGING + || status == BatteryManager.BATTERY_STATUS_FULL) { + if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) { + // Battery is full or charging and nearly full. + ledValues.setColor(mBatteryFullARGB); + ledValues.setSolid(); + } else { + // Battery is charging and not nearly full. + ledValues.setColor(mBatteryMediumARGB); + ledValues.setSolid(); + } + } + + // If a color was set, enable light. + if (ledValues.getColor() != 0) { + ledValues.setEnabled(true); + } + if (DEBUG) { + Slog.i(TAG, "calcLights output: ledValues={ " + ledValues + " }"); + } + } + + class SettingsObserver extends ContentObserver { + SettingsObserver(Handler handler) { + super(handler); + } + + void observe() { + ContentResolver resolver = mContext.getContentResolver(); + + // Battery light enabled + resolver.registerContentObserver(LineageSettings.System.getUriFor( + LineageSettings.System.BATTERY_LIGHT_ENABLED), false, this, + UserHandle.USER_ALL); + + // Low battery pulse + resolver.registerContentObserver(LineageSettings.System.getUriFor( + LineageSettings.System.BATTERY_LIGHT_PULSE), false, this, + UserHandle.USER_ALL); + + // Light colors + if (mMultiColorLed) { + resolver.registerContentObserver(LineageSettings.System.getUriFor( + LineageSettings.System.BATTERY_LIGHT_LOW_COLOR), false, this, + UserHandle.USER_ALL); + resolver.registerContentObserver(LineageSettings.System.getUriFor( + LineageSettings.System.BATTERY_LIGHT_MEDIUM_COLOR), false, this, + UserHandle.USER_ALL); + resolver.registerContentObserver(LineageSettings.System.getUriFor( + LineageSettings.System.BATTERY_LIGHT_FULL_COLOR), false, this, + UserHandle.USER_ALL); + } + + update(); + } + + @Override + public void onChange(boolean selfChange) { + update(); + } + + private void update() { + ContentResolver resolver = mContext.getContentResolver(); + Resources res = mContext.getResources(); + + // Battery light enabled + mLightEnabled = LineageSettings.System.getInt(resolver, + LineageSettings.System.BATTERY_LIGHT_ENABLED, 1) != 0; + + // Low battery pulse + mLedPulseEnabled = LineageSettings.System.getInt(resolver, + LineageSettings.System.BATTERY_LIGHT_PULSE, 1) != 0; + + // Light colors + mBatteryLowARGB = LineageSettings.System.getInt(resolver, + LineageSettings.System.BATTERY_LIGHT_LOW_COLOR, res.getInteger( + com.android.internal.R.integer.config_notificationsBatteryLowARGB)); + mBatteryMediumARGB = LineageSettings.System.getInt(resolver, + LineageSettings.System.BATTERY_LIGHT_MEDIUM_COLOR, res.getInteger( + com.android.internal.R.integer.config_notificationsBatteryMediumARGB)); + mBatteryFullARGB = LineageSettings.System.getInt(resolver, + LineageSettings.System.BATTERY_LIGHT_FULL_COLOR, res.getInteger( + com.android.internal.R.integer.config_notificationsBatteryFullARGB)); + + mLedUpdater.update(); + } + } +}