doze: Java -> Kotlin + bp -> mk

Change-Id: I377658589af22c58ddbf1768f4c89d06594d2762
This commit is contained in:
LuK1337
2021-09-18 21:23:47 +02:00
parent 5d62057c70
commit c7f76a731f
16 changed files with 535 additions and 727 deletions

21
doze/Android.bp Normal file
View File

@@ -0,0 +1,21 @@
android_app {
name: "OplusDoze",
defaults: ["SettingsLibDefaults"],
srcs: ["src/**/*.kt"],
resource_dirs: ["res"],
certificate: "platform",
platform_apis: true,
system_ext_specific: true,
static_libs: [
"androidx.core_core",
"androidx.preference_preference",
"org.lineageos.settings.resources",
],
optimize: {
proguard_flags_files: ["proguard.flags"],
},
}

View File

@@ -1,28 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := OplusDoze
LOCAL_CERTIFICATE := platform
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_PRIVILEGED_MODULE := true
LOCAL_USE_AAPT2 := true
LOCAL_STATIC_ANDROID_LIBRARIES := \
androidx.core_core \
androidx.preference_preference
LOCAL_RESOURCE_DIR := \
$(LOCAL_PATH)/res \
$(TOP)/packages/resources/devicesettings/res
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
include frameworks/base/packages/SettingsLib/common.mk
include $(BUILD_PACKAGE)

View File

@@ -1,35 +0,0 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
* 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.settings.doze;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class BootCompletedReceiver extends BroadcastReceiver {
private static final boolean DEBUG = false;
private static final String TAG = "OplusDoze";
@Override
public void onReceive(final Context context, Intent intent) {
if (DEBUG) Log.d(TAG, "Received boot completed intent");
Utils.checkDozeService(context);
}
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.settings.doze
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
class BootCompletedReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "Starting")
Utils.checkDozeService(context)
}
companion object {
private const val TAG = "OplusDoze"
}
}

View File

@@ -1,97 +0,0 @@
/*
* Copyright (c) 2015 The CyanogenMod Project
* 2017-2018 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.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
public class DozeService extends Service {
private static final String TAG = "DozeService";
private static final boolean DEBUG = false;
private PickupSensor mPickupSensor;
private PocketSensor mPocketSensor;
@Override
public void onCreate() {
if (DEBUG) Log.d(TAG, "Creating service");
mPickupSensor = new PickupSensor(this);
mPocketSensor = new PocketSensor(this);
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenStateReceiver, screenStateFilter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (DEBUG) Log.d(TAG, "Starting service");
return START_STICKY;
}
@Override
public void onDestroy() {
if (DEBUG) Log.d(TAG, "Destroying service");
super.onDestroy();
this.unregisterReceiver(mScreenStateReceiver);
mPickupSensor.disable();
mPocketSensor.disable();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void onDisplayOn() {
if (DEBUG) Log.d(TAG, "Display on");
if (Utils.isPickUpEnabled(this)) {
mPickupSensor.disable();
}
if (Utils.isPocketEnabled(this)) {
mPocketSensor.disable();
}
}
private void onDisplayOff() {
if (DEBUG) Log.d(TAG, "Display off");
if (Utils.isPickUpEnabled(this)) {
mPickupSensor.enable();
}
if (Utils.isPocketEnabled(this)) {
mPocketSensor.enable();
}
}
private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
onDisplayOn();
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
onDisplayOff();
}
}
};
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.settings.doze
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.IBinder
import android.util.Log
class DozeService : Service() {
private lateinit var pickupSensor: PickupSensor
private lateinit var pocketSensor: PocketSensor
private val screenStateReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
Intent.ACTION_SCREEN_ON -> onDisplayOn()
Intent.ACTION_SCREEN_OFF -> onDisplayOff()
}
}
}
override fun onCreate() {
Log.d(TAG, "Creating service")
pickupSensor = PickupSensor(this, resources.getString(R.string.pickup_sensor_type))
pocketSensor = PocketSensor(this, resources.getString(R.string.pocket_sensor_type))
val screenStateFilter = IntentFilter()
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON)
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF)
registerReceiver(screenStateReceiver, screenStateFilter)
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(screenStateReceiver)
pickupSensor.disable()
pocketSensor.disable()
}
override fun onBind(intent: Intent): IBinder? = null
private fun onDisplayOn() {
if (Utils.isPickUpEnabled(this)) {
pickupSensor.disable()
}
if (Utils.isPocketEnabled(this)) {
pocketSensor.disable()
}
}
private fun onDisplayOff() {
if (Utils.isPickUpEnabled(this)) {
pickupSensor.enable()
}
if (Utils.isPocketEnabled(this)) {
pocketSensor.enable()
}
}
companion object {
private const val TAG = "DozeService"
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) 2015-2016 The CyanogenMod Project
* 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.settings.doze;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class DozeSettingsActivity extends PreferenceActivity {
private static final String TAG_DOZE = "doze";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content,
new DozeSettingsFragment(), TAG_DOZE).commit();
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.settings.doze
import android.os.Bundle
import android.preference.PreferenceActivity
class DozeSettingsActivity : PreferenceActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fragmentManager
.beginTransaction()
.replace(android.R.id.content, DozeSettingsFragment(), TAG)
.commit()
}
companion object {
private const val TAG = "DozeSettingsActivity"
}
}

View File

@@ -1,198 +0,0 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
* 2017-2019 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.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
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;
import androidx.preference.PreferenceFragment;
import androidx.preference.SwitchPreference;
public class DozeSettingsFragment extends PreferenceFragment implements OnPreferenceChangeListener,
CompoundButton.OnCheckedChangeListener {
private TextView mTextView;
private View mSwitchBar;
private SwitchPreference mAlwaysOnDisplayPreference;
private ListPreference mPickUpPreference;
private SwitchPreference mPocketPreference;
private Handler mHandler = new Handler();
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.doze_settings);
final ActionBar actionBar = getActivity().getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
SharedPreferences prefs = getActivity().getSharedPreferences("doze_settings",
Activity.MODE_PRIVATE);
if (savedInstanceState == null && !prefs.getBoolean("first_help_shown", false)) {
showHelp();
}
boolean dozeEnabled = Utils.isDozeEnabled(getActivity());
mAlwaysOnDisplayPreference = (SwitchPreference) findPreference(Utils.ALWAYS_ON_DISPLAY);
mAlwaysOnDisplayPreference.setEnabled(dozeEnabled);
mAlwaysOnDisplayPreference.setChecked(Utils.isAlwaysOnEnabled(getActivity()));
mAlwaysOnDisplayPreference.setOnPreferenceChangeListener(this);
PreferenceCategory pickupSensorCategory = (PreferenceCategory) getPreferenceScreen().
findPreference(Utils.CATEG_PICKUP_SENSOR);
PreferenceCategory proximitySensorCategory = (PreferenceCategory) getPreferenceScreen().
findPreference(Utils.CATEG_PROX_SENSOR);
mPickUpPreference = (ListPreference) findPreference(Utils.GESTURE_PICK_UP_KEY);
mPickUpPreference.setEnabled(dozeEnabled);
mPickUpPreference.setOnPreferenceChangeListener(this);
mPocketPreference = (SwitchPreference) findPreference(Utils.GESTURE_POCKET_KEY);
mPocketPreference.setEnabled(dozeEnabled);
mPocketPreference.setOnPreferenceChangeListener(this);
// Hide AOD if not supported and set all its dependents otherwise
if (!Utils.alwaysOnDisplayAvailable(getActivity())) {
getPreferenceScreen().removePreference(mAlwaysOnDisplayPreference);
} else {
pickupSensorCategory.setDependency(Utils.ALWAYS_ON_DISPLAY);
proximitySensorCategory.setDependency(Utils.ALWAYS_ON_DISPLAY);
}
// Hide pickup sensor category if its sensor type is empty
if (getString(R.string.pickup_sensor_type).isEmpty()) {
getPreferenceScreen().removePreference(pickupSensorCategory);
}
// Hide proximity sensor category if its sensor type is empty
if (getString(R.string.pocket_sensor_type).isEmpty()) {
getPreferenceScreen().removePreference(proximitySensorCategory);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = LayoutInflater.from(getContext()).inflate(R.layout.doze, container, false);
((ViewGroup) view).addView(super.onCreateView(inflater, container, savedInstanceState));
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
boolean dozeEnabled = Utils.isDozeEnabled(getActivity());
mTextView = view.findViewById(R.id.switch_text);
mTextView.setText(getString(dozeEnabled ?
R.string.switch_bar_on : R.string.switch_bar_off));
mSwitchBar = view.findViewById(R.id.switch_bar);
Switch switchWidget = mSwitchBar.findViewById(android.R.id.switch_widget);
switchWidget.setChecked(dozeEnabled);
switchWidget.setOnCheckedChangeListener(this);
mSwitchBar.setActivated(dozeEnabled);
mSwitchBar.setOnClickListener(v -> {
switchWidget.setChecked(!switchWidget.isChecked());
mSwitchBar.setActivated(switchWidget.isChecked());
});
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (Utils.ALWAYS_ON_DISPLAY.equals(preference.getKey())) {
Utils.enableAlwaysOn(getActivity(), (Boolean) newValue);
}
mHandler.post(() -> Utils.checkDozeService(getActivity()));
return true;
}
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
Utils.enableDoze(getActivity(), isChecked);
Utils.checkDozeService(getActivity());
mTextView.setText(getString(isChecked ? R.string.switch_bar_on : R.string.switch_bar_off));
mSwitchBar.setActivated(isChecked);
if (!isChecked) {
Utils.enableAlwaysOn(getActivity(), false);
mAlwaysOnDisplayPreference.setChecked(false);
}
mAlwaysOnDisplayPreference.setEnabled(isChecked);
mPickUpPreference.setEnabled(isChecked);
mPocketPreference.setEnabled(isChecked);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
getActivity().onBackPressed();
return true;
}
return false;
}
private static class HelpDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.doze_settings_help_title)
.setMessage(R.string.doze_settings_help_text)
.setNegativeButton(R.string.dialog_ok, (dialog, which) -> dialog.cancel())
.create();
}
@Override
public void onCancel(DialogInterface dialog) {
getActivity().getSharedPreferences("doze_settings", Activity.MODE_PRIVATE)
.edit()
.putBoolean("first_help_shown", true)
.commit();
}
}
private void showHelp() {
HelpDialogFragment fragment = new HelpDialogFragment();
fragment.show(getFragmentManager(), "help_dialog");
}
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.settings.doze
import android.app.Activity
import android.app.AlertDialog
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
import android.widget.Switch
import android.widget.TextView
import androidx.preference.*
class DozeSettingsFragment : PreferenceFragment(), Preference.OnPreferenceChangeListener,
CompoundButton.OnCheckedChangeListener {
private lateinit var alwaysOnDisplayPreference: SwitchPreference
private lateinit var switchBar: View
private lateinit var textView: TextView
private var pickUpPreference: ListPreference? = null
private var pocketPreference: SwitchPreference? = null
private val handler = Handler(Looper.getMainLooper())
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.doze_settings)
activity.actionBar?.setDisplayHomeAsUpEnabled(true)
val prefs = activity.getSharedPreferences("doze_settings", Activity.MODE_PRIVATE)!!
if (savedInstanceState == null && !prefs.getBoolean("first_help_shown", false)) {
AlertDialog.Builder(context)
.setTitle(R.string.doze_settings_help_title)
.setMessage(R.string.doze_settings_help_text)
.setNegativeButton(R.string.dialog_ok) { _, _ ->
prefs.edit().putBoolean("first_help_shown", true).apply()
}
.show()
}
val dozeEnabled = Utils.isDozeEnabled(context)
alwaysOnDisplayPreference = findPreference(Utils.ALWAYS_ON_DISPLAY)!!
alwaysOnDisplayPreference.isEnabled = dozeEnabled
alwaysOnDisplayPreference.isChecked = Utils.isAlwaysOnEnabled(context)
alwaysOnDisplayPreference.onPreferenceChangeListener = this
val pickupSensorCategory =
preferenceScreen.findPreference<PreferenceCategory>(Utils.CATEGORY_PICKUP_SENSOR)
if (getString(R.string.pickup_sensor_type).isEmpty()) {
preferenceScreen.removePreference(pickupSensorCategory)
}
val proximitySensorCategory =
preferenceScreen.findPreference<PreferenceCategory>(Utils.CATEGORY_PROXIMITY_SENSOR)
if (getString(R.string.pocket_sensor_type).isEmpty()) {
preferenceScreen.removePreference(proximitySensorCategory)
}
pickUpPreference = findPreference(Utils.GESTURE_PICK_UP_KEY)
pickUpPreference?.isEnabled = dozeEnabled
pickUpPreference?.onPreferenceChangeListener = this
pocketPreference = findPreference(Utils.GESTURE_POCKET_KEY)
pocketPreference?.isEnabled = dozeEnabled
pocketPreference?.onPreferenceChangeListener = this
// Hide AOD if not supported and set all its dependents otherwise
if (!Utils.alwaysOnDisplayAvailable(context)) {
preferenceScreen.removePreference(alwaysOnDisplayPreference)
} else {
pickupSensorCategory?.dependency = Utils.ALWAYS_ON_DISPLAY
proximitySensorCategory?.dependency = Utils.ALWAYS_ON_DISPLAY
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
val view = LayoutInflater.from(context).inflate(R.layout.doze, container, false)
(view as ViewGroup).addView(super.onCreateView(inflater, container, savedInstanceState))
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val dozeEnabled = Utils.isDozeEnabled(context)
textView = view.findViewById(R.id.switch_text)
textView.text =
getString(if (dozeEnabled) R.string.switch_bar_on else R.string.switch_bar_off)
switchBar = view.findViewById(R.id.switch_bar)
val switchWidget = switchBar.findViewById<Switch>(android.R.id.switch_widget)
switchWidget.isChecked = dozeEnabled
switchWidget.setOnCheckedChangeListener(this)
switchBar.isActivated = dozeEnabled
switchBar.setOnClickListener {
switchWidget.isChecked = !switchWidget.isChecked
switchBar.isActivated = switchWidget.isChecked
}
}
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
if (preference.key == Utils.ALWAYS_ON_DISPLAY) {
Utils.enableAlwaysOn(context, newValue as Boolean)
}
handler.post { Utils.checkDozeService(context) }
return true
}
override fun onCheckedChanged(compoundButton: CompoundButton, isChecked: Boolean) {
Utils.enableDoze(context, isChecked)
Utils.checkDozeService(context)
textView.text =
getString(if (isChecked) R.string.switch_bar_on else R.string.switch_bar_off)
switchBar.isActivated = isChecked
if (!isChecked) {
Utils.enableAlwaysOn(context, false)
alwaysOnDisplayPreference.isChecked = false
}
alwaysOnDisplayPreference.isEnabled = isChecked
pickUpPreference?.isEnabled = isChecked
pocketPreference?.isEnabled = isChecked
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.home -> {
activity.onBackPressed()
true
}
else -> false
}
}
}

View File

@@ -1,110 +0,0 @@
/*
* Copyright (c) 2015 The CyanogenMod Project
* 2017-2018 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.PowerManager;
import android.os.PowerManager.WakeLock;
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 PickupSensor implements SensorEventListener {
private static final boolean DEBUG = false;
private static final String TAG = "PickupSensor";
private static final int MIN_PULSE_INTERVAL_MS = 2500;
private static final int MIN_WAKEUP_INTERVAL_MS = 1000;
private static final int WAKELOCK_TIMEOUT_MS = 300;
private PowerManager mPowerManager;
private SensorManager mSensorManager;
private Sensor mSensor;
private WakeLock mWakeLock;
private Context mContext;
private ExecutorService mExecutorService;
private long mEntryTimestamp;
public PickupSensor(Context context) {
mContext = context;
mPowerManager = mContext.getSystemService(PowerManager.class);
mSensorManager = mContext.getSystemService(SensorManager.class);
mSensor = Utils.getSensor(mSensorManager,
context.getResources().getString(R.string.pickup_sensor_type));
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
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]);
long delta = SystemClock.elapsedRealtime() - mEntryTimestamp;
if (delta < MIN_PULSE_INTERVAL_MS) {
return;
}
mEntryTimestamp = SystemClock.elapsedRealtime();
if (event.values[0] == 1) {
if (Utils.isPickUpSetToWake(mContext)) {
mWakeLock.acquire(WAKELOCK_TIMEOUT_MS);
mPowerManager.wakeUpWithProximityCheck(SystemClock.uptimeMillis(),
PowerManager.WAKE_REASON_GESTURE, TAG);
} else {
Utils.launchDozePulse(mContext);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
/* Empty */
}
protected void enable() {
if (mSensor == null) return;
if (DEBUG) Log.d(TAG, "Enabling");
submit(() -> {
mEntryTimestamp = SystemClock.elapsedRealtime();
mSensorManager.registerListener(this, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
});
}
protected void disable() {
if (mSensor == null) return;
if (DEBUG) Log.d(TAG, "Disabling");
submit(() -> {
mSensorManager.unregisterListener(this, mSensor);
});
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
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.PowerManager
import android.os.SystemClock
import android.util.Log
import java.util.concurrent.Executors
class PickupSensor(private val context: Context, sensorType: String) : SensorEventListener {
private val powerManager = context.getSystemService(PowerManager::class.java)
private val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG)
private val sensorManager = context.getSystemService(SensorManager::class.java)
private val sensor = Utils.getSensor(sensorManager, sensorType)
private val executorService = Executors.newSingleThreadExecutor()
private var entryTimestamp = 0L
override fun onSensorChanged(event: SensorEvent) {
if (DEBUG) Log.d(TAG, "Got sensor event: ${event.values[0]}")
val delta = SystemClock.elapsedRealtime() - entryTimestamp
if (delta < MIN_PULSE_INTERVAL_MS) {
return
}
entryTimestamp = SystemClock.elapsedRealtime()
if (event.values[0] == 1.0f) {
if (Utils.isPickUpSetToWake(context)) {
wakeLock.acquire(WAKELOCK_TIMEOUT_MS)
powerManager.wakeUpWithProximityCheck(
SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, TAG
)
} else {
Utils.launchDozePulse(context)
}
}
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
fun enable() {
if (sensor != null) {
Log.d(TAG, "Enabling")
executorService.submit {
entryTimestamp = SystemClock.elapsedRealtime()
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL)
}
}
}
fun disable() {
if (sensor != null) {
Log.d(TAG, "Disabling")
executorService.submit {
sensorManager.unregisterListener(this, sensor)
}
}
}
companion object {
private const val TAG = "PickupSensor"
private const val DEBUG = false
private const val MIN_PULSE_INTERVAL_MS = 2500L
private const val WAKELOCK_TIMEOUT_MS = 300L
}
}

View File

@@ -1,96 +0,0 @@
/*
* Copyright (c) 2016 The CyanogenMod Project
* Copyright (c) 2018 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 PocketSensor implements SensorEventListener {
private static final boolean DEBUG = false;
private static final String TAG = "PocketSensor";
private static final int MIN_PULSE_INTERVAL_MS = 2500;
private SensorManager mSensorManager;
private Sensor mSensor;
private Context mContext;
private ExecutorService mExecutorService;
private long mEntryTimestamp;
public PocketSensor(Context context) {
mContext = context;
mSensorManager = mContext.getSystemService(SensorManager.class);
mSensor = Utils.getSensor(mSensorManager,
context.getResources().getString(R.string.pocket_sensor_type));
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]);
long delta = SystemClock.elapsedRealtime() - mEntryTimestamp;
if (delta < MIN_PULSE_INTERVAL_MS) {
return;
}
mEntryTimestamp = SystemClock.elapsedRealtime();
if (event.values[0] == 0.0) {
Utils.launchDozePulse(mContext);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
/* Empty */
}
protected void enable() {
if (mSensor == null) return;
if (DEBUG) Log.d(TAG, "Enabling");
submit(() -> {
mEntryTimestamp = SystemClock.elapsedRealtime();
mSensorManager.registerListener(this, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
});
}
protected void disable() {
if (mSensor == null) return;
if (DEBUG) Log.d(TAG, "Disabling");
submit(() -> {
mSensorManager.unregisterListener(this, mSensor);
});
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
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.Executors
class PocketSensor(private val context: Context, sensorType: String) : SensorEventListener {
private val sensorManager = context.getSystemService(SensorManager::class.java)
private val sensor = Utils.getSensor(sensorManager, sensorType)
private val executorService = Executors.newSingleThreadExecutor()
private var entryTimestamp = 0L
override fun onSensorChanged(event: SensorEvent) {
if (DEBUG) Log.d(TAG, "Got sensor event: ${event.values[0]}")
val delta = SystemClock.elapsedRealtime() - entryTimestamp
if (delta < MIN_PULSE_INTERVAL_MS) {
return
}
entryTimestamp = SystemClock.elapsedRealtime()
if (event.values[0] == 0.0f) {
Utils.launchDozePulse(context)
}
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
fun enable() {
if (sensor != null) {
Log.d(TAG, "Enabling")
executorService.submit {
entryTimestamp = SystemClock.elapsedRealtime()
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL)
}
}
}
fun disable() {
if (sensor != null) {
Log.d(TAG, "Disabling")
executorService.submit {
sensorManager.unregisterListener(this, sensor)
}
}
}
companion object {
private const val TAG = "PocketSensor"
private const val DEBUG = false
private const val MIN_PULSE_INTERVAL_MS = 2500L
}
}

View File

@@ -1,129 +0,0 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
* 2017-2019 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.content.Intent;
import android.hardware.display.AmbientDisplayConfiguration;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import androidx.preference.PreferenceManager;
import static android.provider.Settings.Secure.DOZE_ALWAYS_ON;
import static android.provider.Settings.Secure.DOZE_ENABLED;
public final class Utils {
private static final String TAG = "DozeUtils";
private static final boolean DEBUG = false;
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 CATEG_PICKUP_SENSOR = "pickup_sensor";
protected static final String CATEG_PROX_SENSOR = "proximity_sensor";
protected static final String GESTURE_PICK_UP_KEY = "gesture_pick_up_type";
protected static final String GESTURE_POCKET_KEY = "gesture_pocket";
protected static void startService(Context context) {
if (DEBUG) Log.d(TAG, "Starting service");
context.startServiceAsUser(new Intent(context, DozeService.class),
UserHandle.CURRENT);
}
protected static void stopService(Context context) {
if (DEBUG) Log.d(TAG, "Stopping service");
context.stopServiceAsUser(new Intent(context, DozeService.class),
UserHandle.CURRENT);
}
protected static void checkDozeService(Context context) {
if (isDozeEnabled(context) && !isAlwaysOnEnabled(context) && areGesturesEnabled(context)) {
startService(context);
} else {
stopService(context);
}
}
protected static boolean isDozeEnabled(Context context) {
return Settings.Secure.getInt(context.getContentResolver(),
DOZE_ENABLED, 1) != 0;
}
protected static boolean enableDoze(Context context, boolean enable) {
return Settings.Secure.putInt(context.getContentResolver(),
DOZE_ENABLED, enable ? 1 : 0);
}
protected static void launchDozePulse(Context context) {
if (DEBUG) Log.d(TAG, "Launch doze pulse");
context.sendBroadcastAsUser(new Intent(DOZE_INTENT),
new UserHandle(UserHandle.USER_CURRENT));
}
protected static boolean enableAlwaysOn(Context context, boolean enable) {
return Settings.Secure.putIntForUser(context.getContentResolver(),
DOZE_ALWAYS_ON, enable ? 1 : 0, UserHandle.USER_CURRENT);
}
protected static boolean isAlwaysOnEnabled(Context context) {
return Settings.Secure.getIntForUser(context.getContentResolver(),
DOZE_ALWAYS_ON, 0, UserHandle.USER_CURRENT) != 0;
}
protected static boolean alwaysOnDisplayAvailable(Context context) {
return new AmbientDisplayConfiguration(context).alwaysOnAvailable();
}
protected static boolean isGestureEnabled(Context context, String gesture) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(gesture, false);
}
protected static boolean isPickUpEnabled(Context context) {
return !PreferenceManager.getDefaultSharedPreferences(context)
.getString(GESTURE_PICK_UP_KEY, "0").equals("0");
}
protected static boolean isPickUpSetToWake(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getString(GESTURE_PICK_UP_KEY, "0").equals("2");
}
protected static boolean isPocketEnabled(Context context) {
return isGestureEnabled(context, GESTURE_POCKET_KEY);
}
public static boolean areGesturesEnabled(Context context) {
return isPickUpEnabled(context) || isPocketEnabled(context);
}
protected static Sensor getSensor(SensorManager sm, String type) {
for (Sensor sensor : sm.getSensorList(Sensor.TYPE_ALL)) {
if (type.equals(sensor.getStringType())) {
return sensor;
}
}
return null;
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2021 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.settings.doze
import android.content.Context
import android.content.Intent
import android.hardware.Sensor
import android.hardware.SensorManager
import android.hardware.display.AmbientDisplayConfiguration
import android.os.UserHandle
import android.provider.Settings
import android.provider.Settings.Secure.DOZE_ALWAYS_ON
import android.provider.Settings.Secure.DOZE_ENABLED
import android.util.Log
import androidx.preference.PreferenceManager
object Utils {
private const val TAG = "DozeUtils"
private const val DOZE_INTENT = "com.android.systemui.doze.pulse"
const val ALWAYS_ON_DISPLAY = "always_on_display"
const val CATEGORY_PICKUP_SENSOR = "pickup_sensor"
const val CATEGORY_PROXIMITY_SENSOR = "proximity_sensor"
const val GESTURE_PICK_UP_KEY = "gesture_pick_up_type"
const val GESTURE_POCKET_KEY = "gesture_pocket"
private fun startService(context: Context) {
Log.d(TAG, "Starting service")
context.startServiceAsUser(Intent(context, DozeService::class.java), UserHandle.CURRENT)
}
private fun stopService(context: Context) {
Log.d(TAG, "Stopping service")
context.stopServiceAsUser(Intent(context, DozeService::class.java), UserHandle.CURRENT)
}
fun checkDozeService(context: Context) {
if (isDozeEnabled(context) && !isAlwaysOnEnabled(context) && areGesturesEnabled(context)) {
startService(context)
} else {
stopService(context)
}
}
fun isDozeEnabled(context: Context): Boolean {
return Settings.Secure.getInt(context.contentResolver, DOZE_ENABLED, 1) != 0
}
fun enableDoze(context: Context, enable: Boolean): Boolean {
return Settings.Secure.putInt(context.contentResolver, DOZE_ENABLED, if (enable) 1 else 0)
}
fun launchDozePulse(context: Context) {
Log.d(TAG, "Launch doze pulse")
context.sendBroadcastAsUser(Intent(DOZE_INTENT), UserHandle(UserHandle.USER_CURRENT))
}
fun enableAlwaysOn(context: Context, enable: Boolean): Boolean {
return Settings.Secure.putIntForUser(
context.contentResolver, DOZE_ALWAYS_ON, if (enable) 1 else 0, UserHandle.USER_CURRENT
)
}
fun isAlwaysOnEnabled(context: Context): Boolean {
return Settings.Secure.getIntForUser(
context.contentResolver, DOZE_ALWAYS_ON, 0, UserHandle.USER_CURRENT
) != 0
}
fun alwaysOnDisplayAvailable(context: Context): Boolean {
return AmbientDisplayConfiguration(context).alwaysOnAvailable()
}
private fun isGestureEnabled(context: Context?, gesture: String?): Boolean {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(gesture, false)
}
fun isPickUpEnabled(context: Context?): Boolean {
return PreferenceManager.getDefaultSharedPreferences(context)
.getString(GESTURE_PICK_UP_KEY, "0") != "0"
}
fun isPickUpSetToWake(context: Context?): Boolean {
return PreferenceManager.getDefaultSharedPreferences(context)
.getString(GESTURE_PICK_UP_KEY, "0") == "2"
}
fun isPocketEnabled(context: Context?): Boolean {
return isGestureEnabled(context, GESTURE_POCKET_KEY)
}
private fun areGesturesEnabled(context: Context?): Boolean {
return isPickUpEnabled(context) || isPocketEnabled(context)
}
fun getSensor(sm: SensorManager, type: String?): Sensor? {
return sm.getSensorList(Sensor.TYPE_ALL).find { it.stringType == type }
}
}