diff --git a/parts/res/drawable/ic_doze_brightness_auto.xml b/parts/res/drawable/ic_doze_brightness_auto.xml
new file mode 100644
index 0000000..81d74f5
--- /dev/null
+++ b/parts/res/drawable/ic_doze_brightness_auto.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/parts/res/drawable/ic_doze_brightness_high.xml b/parts/res/drawable/ic_doze_brightness_high.xml
new file mode 100644
index 0000000..43dc498
--- /dev/null
+++ b/parts/res/drawable/ic_doze_brightness_high.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/parts/res/drawable/ic_doze_brightness_low.xml b/parts/res/drawable/ic_doze_brightness_low.xml
new file mode 100644
index 0000000..ec13c12
--- /dev/null
+++ b/parts/res/drawable/ic_doze_brightness_low.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/parts/res/values/arrays.xml b/parts/res/values/arrays.xml
new file mode 100644
index 0000000..46137ab
--- /dev/null
+++ b/parts/res/values/arrays.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ - Low brightness
+ - High brightness
+ - Adaptive brightness
+
+
+ - 0
+ - 1
+ - 2
+
+
diff --git a/parts/res/values/strings.xml b/parts/res/values/strings.xml
new file mode 100644
index 0000000..d9249a3
--- /dev/null
+++ b/parts/res/values/strings.xml
@@ -0,0 +1,20 @@
+
+
+
+ Doze brightness
+ %s mode is enabled
+
diff --git a/parts/res/xml/doze_settings.xml b/parts/res/xml/doze_settings.xml
index 3a068c0..01ef6c0 100644
--- a/parts/res/xml/doze_settings.xml
+++ b/parts/res/xml/doze_settings.xml
@@ -25,6 +25,14 @@
android:summary="@string/ambient_display_always_on_summary"
android:persistent="false" />
+
+
diff --git a/parts/src/org/lineageos/settings/BootCompletedReceiver.java b/parts/src/org/lineageos/settings/BootCompletedReceiver.java
index 672621e..08b9f1d 100644
--- a/parts/src/org/lineageos/settings/BootCompletedReceiver.java
+++ b/parts/src/org/lineageos/settings/BootCompletedReceiver.java
@@ -32,6 +32,6 @@ public class BootCompletedReceiver extends BroadcastReceiver {
public void onReceive(final Context context, Intent intent) {
if (DEBUG)
Log.d(TAG, "Received boot completed intent");
- DozeUtils.checkDozeService(context);
+ DozeUtils.onBootCompleted(context);
}
}
diff --git a/parts/src/org/lineageos/settings/doze/AodSensor.java b/parts/src/org/lineageos/settings/doze/AodSensor.java
new file mode 100644
index 0000000..0cb6a16
--- /dev/null
+++ b/parts/src/org/lineageos/settings/doze/AodSensor.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2021 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.settings.doze;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.SystemClock;
+import android.util.Log;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+public class AodSensor implements SensorEventListener {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "AodSensor";
+
+ private SensorManager mSensorManager;
+ private Sensor mSensor;
+ private Context mContext;
+ private ExecutorService mExecutorService;
+
+ public AodSensor(Context context) {
+ mContext = context;
+ mSensorManager = mContext.getSystemService(SensorManager.class);
+ mSensor = DozeUtils.getSensor(mSensorManager, "xiaomi.sensor.aod");
+ mExecutorService = Executors.newSingleThreadExecutor();
+ }
+
+ private Future> submit(Runnable runnable) { return mExecutorService.submit(runnable); }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (DEBUG) {
+ Log.d(TAG, "Got sensor event: " + event.values[0]);
+ }
+
+ if (event.values[0] == 3 || event.values[0] == 5) {
+ DozeUtils.setDozeMode(DozeUtils.DOZE_MODE_LBM);
+ } else if (event.values[0] == 4) {
+ DozeUtils.setDozeMode(DozeUtils.DOZE_MODE_HBM);
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ /* Empty */
+ }
+
+ protected void enable() {
+ if (DEBUG) {
+ Log.d(TAG, "Enabling");
+ }
+ submit(() -> {
+ mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
+ });
+ }
+
+ protected void disable() {
+ if (DEBUG) {
+ Log.d(TAG, "Disabling");
+ }
+ submit(() -> { mSensorManager.unregisterListener(this, mSensor); });
+ }
+}
diff --git a/parts/src/org/lineageos/settings/doze/DozeService.java b/parts/src/org/lineageos/settings/doze/DozeService.java
index 0c9c61a..84641e1 100644
--- a/parts/src/org/lineageos/settings/doze/DozeService.java
+++ b/parts/src/org/lineageos/settings/doze/DozeService.java
@@ -29,6 +29,7 @@ public class DozeService extends Service {
private static final String TAG = "DozeService";
private static final boolean DEBUG = false;
+ private AodSensor mAodSensor;
private ProximitySensor mProximitySensor;
private PickupSensor mPickupSensor;
@@ -36,6 +37,7 @@ public class DozeService extends Service {
public void onCreate() {
if (DEBUG)
Log.d(TAG, "Creating service");
+ mAodSensor = new AodSensor(this);
mProximitySensor = new ProximitySensor(this);
mPickupSensor = new PickupSensor(this);
@@ -76,6 +78,9 @@ public class DozeService extends Service {
if (DozeUtils.isHandwaveGestureEnabled(this) || DozeUtils.isPocketGestureEnabled(this)) {
mProximitySensor.disable();
}
+ if (DozeUtils.isDozeAutoBrightnessEnabled(this)) {
+ mAodSensor.disable();
+ }
}
private void onDisplayOff() {
@@ -87,6 +92,9 @@ public class DozeService extends Service {
if (DozeUtils.isHandwaveGestureEnabled(this) || DozeUtils.isPocketGestureEnabled(this)) {
mProximitySensor.enable();
}
+ if (DozeUtils.isDozeAutoBrightnessEnabled(this)) {
+ mAodSensor.enable();
+ }
}
private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
diff --git a/parts/src/org/lineageos/settings/doze/DozeSettingsFragment.java b/parts/src/org/lineageos/settings/doze/DozeSettingsFragment.java
index ea229a5..69dbd4f 100644
--- a/parts/src/org/lineageos/settings/doze/DozeSettingsFragment.java
+++ b/parts/src/org/lineageos/settings/doze/DozeSettingsFragment.java
@@ -34,6 +34,7 @@ import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
+import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceCategory;
@@ -48,6 +49,7 @@ public class DozeSettingsFragment extends PreferenceFragment
private View mSwitchBar;
private SwitchPreference mAlwaysOnDisplayPreference;
+ private ListPreference mDozeBrightnessPreference;
private SwitchPreference mWakeOnGesturePreference;
private SwitchPreference mPickUpPreference;
private SwitchPreference mHandwavePreference;
@@ -74,6 +76,11 @@ public class DozeSettingsFragment extends PreferenceFragment
mAlwaysOnDisplayPreference.setChecked(DozeUtils.isAlwaysOnEnabled(getActivity()));
mAlwaysOnDisplayPreference.setOnPreferenceChangeListener(this);
+ mDozeBrightnessPreference = (ListPreference) findPreference(DozeUtils.DOZE_BRIGHTNESS_KEY);
+ mDozeBrightnessPreference.setEnabled(
+ dozeEnabled && DozeUtils.isAlwaysOnEnabled(getActivity()));
+ mDozeBrightnessPreference.setOnPreferenceChangeListener(this);
+
mWakeOnGesturePreference = (SwitchPreference) findPreference(DozeUtils.WAKE_ON_GESTURE_KEY);
mWakeOnGesturePreference.setEnabled(dozeEnabled);
mWakeOnGesturePreference.setOnPreferenceChangeListener(this);
@@ -105,6 +112,7 @@ public class DozeSettingsFragment extends PreferenceFragment
// Hide AOD if not supported and set all its dependents otherwise
if (!DozeUtils.alwaysOnDisplayAvailable(getActivity())) {
getPreferenceScreen().removePreference(mAlwaysOnDisplayPreference);
+ getPreferenceScreen().removePreference(mDozeBrightnessPreference);
} else {
mWakeOnGesturePreference.setDependency(DozeUtils.ALWAYS_ON_DISPLAY);
pickupSensorCategory.setDependency(DozeUtils.ALWAYS_ON_DISPLAY);
@@ -146,6 +154,29 @@ public class DozeSettingsFragment extends PreferenceFragment
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (DozeUtils.ALWAYS_ON_DISPLAY.equals(preference.getKey())) {
DozeUtils.enableAlwaysOn(getActivity(), (Boolean) newValue);
+ if (!(Boolean) newValue) {
+ mDozeBrightnessPreference.setValue(DozeUtils.DOZE_BRIGHTNESS_LBM);
+ } else {
+ mPickUpPreference.setChecked(false);
+ mHandwavePreference.setChecked(false);
+ mPocketPreference.setChecked(false);
+ }
+ mDozeBrightnessPreference.setEnabled((Boolean) newValue);
+ } else if (DozeUtils.DOZE_BRIGHTNESS_KEY.equals(preference.getKey())) {
+ if (!DozeUtils.DOZE_BRIGHTNESS_AUTO.equals((String) newValue)) {
+ DozeUtils.setDozeMode((String) newValue);
+ }
+ switch ((String) newValue) {
+ case DozeUtils.DOZE_BRIGHTNESS_LBM:
+ mDozeBrightnessPreference.setIcon(R.drawable.ic_doze_brightness_low);
+ break;
+ case DozeUtils.DOZE_BRIGHTNESS_HBM:
+ mDozeBrightnessPreference.setIcon(R.drawable.ic_doze_brightness_high);
+ break;
+ case DozeUtils.DOZE_BRIGHTNESS_AUTO:
+ mDozeBrightnessPreference.setIcon(R.drawable.ic_doze_brightness_auto);
+ break;
+ }
}
mHandler.post(() -> DozeUtils.checkDozeService(getActivity()));
@@ -164,8 +195,14 @@ public class DozeSettingsFragment extends PreferenceFragment
if (!isChecked) {
DozeUtils.enableAlwaysOn(getActivity(), false);
mAlwaysOnDisplayPreference.setChecked(false);
+ mDozeBrightnessPreference.setValue(DozeUtils.DOZE_BRIGHTNESS_LBM);
+ mPickUpPreference.setChecked(false);
+ mHandwavePreference.setChecked(false);
+ mPocketPreference.setChecked(false);
}
mAlwaysOnDisplayPreference.setEnabled(isChecked);
+ mDozeBrightnessPreference.setEnabled(
+ isChecked && DozeUtils.isAlwaysOnEnabled(getActivity()));
mWakeOnGesturePreference.setEnabled(isChecked);
mPickUpPreference.setEnabled(isChecked);
mHandwavePreference.setEnabled(isChecked);
diff --git a/parts/src/org/lineageos/settings/doze/DozeUtils.java b/parts/src/org/lineageos/settings/doze/DozeUtils.java
index 31814ac..043dab9 100644
--- a/parts/src/org/lineageos/settings/doze/DozeUtils.java
+++ b/parts/src/org/lineageos/settings/doze/DozeUtils.java
@@ -30,6 +30,8 @@ import android.provider.Settings;
import android.util.Log;
import androidx.preference.PreferenceManager;
+import org.lineageos.settings.utils.FileUtils;
+
import static android.provider.Settings.Secure.DOZE_ALWAYS_ON;
import static android.provider.Settings.Secure.DOZE_ENABLED;
@@ -40,6 +42,7 @@ public final class DozeUtils {
private static final String DOZE_INTENT = "com.android.systemui.doze.pulse";
protected static final String ALWAYS_ON_DISPLAY = "always_on_display";
+ protected static final String DOZE_BRIGHTNESS_KEY = "doze_brightness";
protected static final String WAKE_ON_GESTURE_KEY = "wake_on_gesture";
protected static final String CATEG_PICKUP_SENSOR = "pickup_sensor";
protected static final String CATEG_PROX_SENSOR = "proximity_sensor";
@@ -48,6 +51,19 @@ public final class DozeUtils {
protected static final String GESTURE_HAND_WAVE_KEY = "gesture_hand_wave";
protected static final String GESTURE_POCKET_KEY = "gesture_pocket";
+ private static final String DOZE_MODE_PATH =
+ "/sys/devices/platform/soc/soc:qcom,dsi-display/doze_mode";
+ protected static final String DOZE_MODE_HBM = "1";
+ protected static final String DOZE_MODE_LBM = "0";
+
+ protected static final String DOZE_BRIGHTNESS_LBM = "0";
+ protected static final String DOZE_BRIGHTNESS_HBM = "1";
+ protected static final String DOZE_BRIGHTNESS_AUTO = "2";
+
+ public static void onBootCompleted(Context context) {
+ checkDozeService(context);
+ restoreDozeModes(context);
+ }
public static void startService(Context context) {
if (DEBUG)
Log.d(TAG, "Starting service");
@@ -61,13 +77,21 @@ public final class DozeUtils {
}
public static void checkDozeService(Context context) {
- if (isDozeEnabled(context) && !isAlwaysOnEnabled(context) && sensorsEnabled(context)) {
+ if (isDozeEnabled(context)
+ && (!isAlwaysOnEnabled(context) || isDozeAutoBrightnessEnabled(context))
+ && sensorsEnabled(context)) {
startService(context);
} else {
stopService(context);
}
}
+ private static void restoreDozeModes(Context context) {
+ if (isAlwaysOnEnabled(context) && !isDozeAutoBrightnessEnabled(context)) {
+ setDozeMode(PreferenceManager.getDefaultSharedPreferences(context).getString(
+ DOZE_BRIGHTNESS_KEY, String.valueOf(DOZE_BRIGHTNESS_LBM)));
+ }
+ }
protected static boolean getProxCheckBeforePulse(Context context) {
try {
Context con = context.createPackageContext("com.android.systemui", 0);
@@ -118,6 +142,16 @@ public final class DozeUtils {
return new AmbientDisplayConfiguration(context).alwaysOnAvailable();
}
+ protected static boolean setDozeMode(String value) {
+ return FileUtils.writeLine(DOZE_MODE_PATH, value);
+ }
+
+ protected static boolean isDozeAutoBrightnessEnabled(Context context) {
+ return PreferenceManager.getDefaultSharedPreferences(context)
+ .getString(DOZE_BRIGHTNESS_KEY, DOZE_BRIGHTNESS_LBM)
+ .equals(DOZE_BRIGHTNESS_AUTO);
+ }
+
protected static boolean isGestureEnabled(Context context, String gesture) {
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(gesture, false);
}
@@ -139,8 +173,8 @@ public final class DozeUtils {
}
public static boolean sensorsEnabled(Context context) {
- return isPickUpEnabled(context) || isHandwaveGestureEnabled(context)
- || isPocketGestureEnabled(context);
+ return isDozeAutoBrightnessEnabled(context) || isHandwaveGestureEnabled(context)
+ || isPickUpEnabled(context) || isPocketGestureEnabled(context);
}
protected static Sensor getSensor(SensorManager sm, String type) {
diff --git a/rootdir/etc/init.target.rc b/rootdir/etc/init.target.rc
index daa0259..8b985ed 100644
--- a/rootdir/etc/init.target.rc
+++ b/rootdir/etc/init.target.rc
@@ -80,6 +80,10 @@ on boot
chown system system /sys/class/thermal/thermal_message/sconfig
write /sys/class/thermal/thermal_message/sconfig 10
+ # Set doze mode permissions
+ chown system system /sys/devices/platform/soc/soc:qcom,dsi-display/doze_mode
+ chmod 0660 /sys/devices/platform/soc/soc:qcom,dsi-display/doze_mode
+
on property:sys.boot_completed=1
# Set allocstall_threshold to 0
# Set swappiness to 100
diff --git a/sepolicy/vendor/file_contexts b/sepolicy/vendor/file_contexts
index a8a6020..35899bc 100644
--- a/sepolicy/vendor/file_contexts
+++ b/sepolicy/vendor/file_contexts
@@ -8,6 +8,7 @@
/sys/devices/platform/soc/[a-f0-9]+.qcom,mdss_mdp/drm/card([0-3])+/card([0-3])+-DSI-1/panel_info u:object_r:vendor_sysfs_graphics:s0
/sys/devices/platform/soc/soc:qcom,dsi-display/dc_enable u:object_r:sysfs_anti_flicker:s0
/sys/devices/platform/soc/soc:qcom,dsi-display/hbm u:object_r:sysfs_hbm:s0
+/sys/devices/platform/soc/soc:qcom,dsi-display/doze_mode u:object_r:sysfs_doze:s0
# Fingerprint
/dev/goodix_fp u:object_r:fingerprint_device:s0
diff --git a/sepolicy/vendor/system_app.te b/sepolicy/vendor/system_app.te
new file mode 100644
index 0000000..34ef8e5
--- /dev/null
+++ b/sepolicy/vendor/system_app.te
@@ -0,0 +1,3 @@
+type sysfs_doze, sysfs_type, fs_type;
+
+allow system_app sysfs_doze:file rw_file_perms;