davinci: parts: Import from xiaomi_sdm845-common

e261035d91/parts

Change-Id: I442f48780ca020f3e420ee4ccaf8ac07b05457cb
This commit is contained in:
Arian 2020-03-20 23:42:25 +01:00
parent 494d2c91bd
commit 8b5675114b
No known key found for this signature in database
GPG Key ID: 48029380598CE3B9
19 changed files with 1104 additions and 0 deletions

View File

@ -51,6 +51,10 @@ PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.camera.full.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.full.xml \
frameworks/native/data/etc/android.hardware.camera.raw.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.raw.xml
# Device-specific settings
PRODUCT_PACKAGES += \
XiaomiParts
# HIDL
PRODUCT_PACKAGES += \
android.hidl.base@1.0 \

34
parts/Android.mk Normal file
View File

@ -0,0 +1,34 @@
#
# Copyright (C) 2017-2020 The LineageOS Project
#
# SPDX-License-Identifier: Apache-2.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 := XiaomiParts
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)

59
parts/AndroidManifest.xml Normal file
View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-2016 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.lineageos.settings"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="android.uid.system">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<protected-broadcast android:name="com.android.systemui.doze.pulse" />
<uses-sdk
android:minSdkVersion="24"
android:targetSdkVersion="24"/>
<application
android:label="@string/device_settings_app_name"
android:persistent="true">
<receiver android:name=".BootCompletedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:name=".doze.DozeService"
android:permission="XiaomiDozeService">
</service>
<activity
android:name=".doze.DozeSettingsActivity"
android:label="@string/ambient_display_title"
android:theme="@style/Theme.Main">
<intent-filter>
<action android:name="org.lineageos.settings.device.DOZE_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>

3
parts/proguard.flags Normal file
View File

@ -0,0 +1,3 @@
-keep class org.lineageos.settings.doze.* {
*;
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019-2020 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/switchbar_background_color" android:state_activated="false" />
<item android:color="?android:attr/colorAccent" android:state_activated="true" />
</selector>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/switch_bar_bg" />
</shape>

28
parts/res/layout/doze.xml Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2014, The Android Open Source 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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent">
<include layout="@layout/switch_bar" />
</LinearLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Android Open Source 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/switch_bar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="@drawable/switchbar_background"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:clickable="true"
android:gravity="center"
android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent">
<TextView android:id="@+id/switch_text"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingStart="56dp"
android:maxLines="2"
android:ellipsize="end"
android:textAppearance="@android:style/TextAppearance.Material.Title"
android:textColor="?android:attr/textColorPrimaryInverse"
android:textSize="18sp"
android:textAlignment="viewStart" />
<Switch
android:id="@android:id/switch_widget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@null"
android:theme="@style/Theme.Main.SwitchBar.Switch" />
</LinearLayout>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2020 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.
-->
<resources>
<color name="switchbar_switch_track_tint">#82000000</color>
<color name="switchbar_switch_thumb_tint">@android:color/black</color>
</resources>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2020 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.
-->
<resources>
<color name="switchbar_background_color">@*android:color/material_grey_600</color>
<color name="switchbar_switch_track_tint">#BFFFFFFF</color>
<color name="switchbar_switch_thumb_tint">@android:color/white</color>
</resources>

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-2016 The CyanogenMod Project
2017-2020 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.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<style name="Theme.Main" parent="@android:style/Theme.DeviceDefault.Settings">
<item name="dialogPreferenceStyle">@style/Theme.Main.DialogPreferenceStyle</item>
<item name="preferenceCategoryStyle">@style/Theme.Main.PreferenceCategoryStyle</item>
<item name="preferenceFragmentStyle">@style/Theme.Main.PreferenceFragmentStyle</item>
<item name="preferenceStyle">@style/Theme.Main.PreferenceStyle</item>
<item name="preferenceTheme">@style/Theme.Main.PreferenceTheme</item>
<item name="switchPreferenceStyle">@style/Theme.Main.SwitchPreferenceStyle</item>
</style>
<style name="Theme.Main.DialogPreferenceStyle" parent="@style/Theme.Main.PreferenceStyle">
</style>
<style name="Theme.Main.PreferenceCategoryStyle" parent="@*android:style/Preference.DeviceDefault.Category">
<item name="allowDividerAbove">true</item>
<item name="allowDividerBelow">true</item>
<item name="android:layout">@layout/preference_category_material_settings</item>
</style>
<style name="Theme.Main.PreferenceFragmentStyle" parent="@*android:style/PreferenceFragment.Material">
<item name="allowDividerAfterLastItem">false</item>
</style>
<style name="Theme.Main.PreferenceStyle" parent="@*android:style/Preference.DeviceDefault">
<item name="allowDividerAbove">false</item>
<item name="allowDividerBelow">true</item>
<item name="singleLineTitle">false</item>
<item name="android:layout">@layout/preference_material_settings</item>
</style>
<style name="Theme.Main.PreferenceTheme" parent="@style/PreferenceThemeOverlay.SettingsBase">
<item name="preferenceCategoryTitleTextAppearance">
@style/Theme.Main.TextAppearance.CategoryTitle
</item>
</style>
<style name="Theme.Main.SwitchPreferenceStyle" parent="@style/Theme.Main.PreferenceStyle">
<item name="widgetLayout">@*android:layout/preference_widget_switch</item>
</style>
<style name="Theme.Main.SwitchBar" parent="@android:style/ThemeOverlay.Material.ActionBar">
</style>
<style name="Theme.Main.SwitchBar.Switch">
<item name="android:trackTint">@color/switchbar_switch_track_tint</item>
<item name="android:thumbTint">@color/switchbar_switch_thumb_tint</item>
</style>
<style name="Theme.Main.TextAppearance.CategoryTitle"
parent="@*android:style/TextAppearance.DeviceDefault.Body2">
<item name="android:textAllCaps">true</item>
<item name="android:textSize">11sp</item>
<!-- 0.8 Spacing, 0.8/11 = 0.072727273 -->
<item name="android:letterSpacing">0.072727273</item>
</style>
</resources>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The CyanogenMod Project
2018-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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:key="always_on_display"
android:disableDependentsState="true"
android:title="@string/ambient_display_always_on_title"
android:summary="@string/ambient_display_always_on_summary"
android:persistent="false" />
<PreferenceCategory
android:key="pickup_sensor"
android:title="@string/pickup_sensor_title">
<SwitchPreference
android:key="gesture_pick_up"
android:defaultValue="false"
android:title="@string/pick_up_gesture_title"
android:summary="@string/pick_up_gesture_summary" />
</PreferenceCategory>
<PreferenceCategory
android:key="proximity_sensor"
android:title="@string/proximity_sensor_title">
<SwitchPreference
android:key="gesture_hand_wave"
android:defaultValue="false"
android:title="@string/hand_wave_gesture_title"
android:summary="@string/hand_wave_gesture_summary" />
<SwitchPreference
android:key="gesture_pocket"
android:defaultValue="false"
android:title="@string/pocket_gesture_title"
android:summary="@string/pocket_gesture_summary" />
</PreferenceCategory>
</PreferenceScreen>

View File

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

View File

@ -0,0 +1,99 @@
/*
* 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 ProximitySensor mProximitySensor;
private PickupSensor mPickupSensor;
@Override
public void onCreate() {
if (DEBUG) Log.d(TAG, "Creating service");
mProximitySensor = new ProximitySensor(this);
mPickupSensor = new PickupSensor(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);
mProximitySensor.disable();
mPickupSensor.disable();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void onDisplayOn() {
if (DEBUG) Log.d(TAG, "Display on");
if (DozeUtils.isPickUpEnabled(this)) {
mPickupSensor.disable();
}
if (DozeUtils.isHandwaveGestureEnabled(this) ||
DozeUtils.isPocketGestureEnabled(this)) {
mProximitySensor.disable();
}
}
private void onDisplayOff() {
if (DEBUG) Log.d(TAG, "Display off");
if (DozeUtils.isPickUpEnabled(this)) {
mPickupSensor.enable();
}
if (DozeUtils.isHandwaveGestureEnabled(this) ||
DozeUtils.isPocketGestureEnabled(this)) {
mProximitySensor.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,34 @@
/*
* 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,201 @@
/*
* 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.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragment;
import androidx.preference.SwitchPreference;
import org.lineageos.settings.R;
public class DozeSettingsFragment extends PreferenceFragment implements OnPreferenceChangeListener,
CompoundButton.OnCheckedChangeListener {
private TextView mTextView;
private View mSwitchBar;
private SwitchPreference mAlwaysOnDisplayPreference;
private SwitchPreference mPickUpPreference;
private SwitchPreference mHandwavePreference;
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 = DozeUtils.isDozeEnabled(getActivity());
mAlwaysOnDisplayPreference = (SwitchPreference) findPreference(DozeUtils.ALWAYS_ON_DISPLAY);
mAlwaysOnDisplayPreference.setEnabled(dozeEnabled);
mAlwaysOnDisplayPreference.setChecked(DozeUtils.isAlwaysOnEnabled(getActivity()));
mAlwaysOnDisplayPreference.setOnPreferenceChangeListener(this);
PreferenceCategory pickupSensorCategory = (PreferenceCategory) getPreferenceScreen().
findPreference(DozeUtils.CATEG_PICKUP_SENSOR);
PreferenceCategory proximitySensorCategory = (PreferenceCategory) getPreferenceScreen().
findPreference(DozeUtils.CATEG_PROX_SENSOR);
mPickUpPreference = (SwitchPreference) findPreference(DozeUtils.GESTURE_PICK_UP_KEY);
mPickUpPreference.setEnabled(dozeEnabled);
mPickUpPreference.setOnPreferenceChangeListener(this);
mHandwavePreference = (SwitchPreference) findPreference(DozeUtils.GESTURE_HAND_WAVE_KEY);
mHandwavePreference.setEnabled(dozeEnabled);
mHandwavePreference.setOnPreferenceChangeListener(this);
mPocketPreference = (SwitchPreference) findPreference(DozeUtils.GESTURE_POCKET_KEY);
mPocketPreference.setEnabled(dozeEnabled);
mPocketPreference.setOnPreferenceChangeListener(this);
// Hide proximity sensor related features if the device doesn't support them
if (!DozeUtils.getProxCheckBeforePulse(getActivity())) {
getPreferenceScreen().removePreference(proximitySensorCategory);
}
// Hide AOD if not supported and set all its dependents otherwise
if (!DozeUtils.alwaysOnDisplayAvailable(getActivity())) {
getPreferenceScreen().removePreference(mAlwaysOnDisplayPreference);
} else {
pickupSensorCategory.setDependency(DozeUtils.ALWAYS_ON_DISPLAY);
proximitySensorCategory.setDependency(DozeUtils.ALWAYS_ON_DISPLAY);
}
}
@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 = DozeUtils.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 (DozeUtils.ALWAYS_ON_DISPLAY.equals(preference.getKey())) {
DozeUtils.enableAlwaysOn(getActivity(), (Boolean) newValue);
}
mHandler.post(() -> DozeUtils.checkDozeService(getActivity()));
return true;
}
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
DozeUtils.enableDoze(getActivity(), isChecked);
DozeUtils.checkDozeService(getActivity());
mTextView.setText(getString(isChecked ? R.string.switch_bar_on : R.string.switch_bar_off));
mSwitchBar.setActivated(isChecked);
if (!isChecked) {
DozeUtils.enableAlwaysOn(getActivity(), false);
mAlwaysOnDisplayPreference.setChecked(false);
}
mAlwaysOnDisplayPreference.setEnabled(isChecked);
mPickUpPreference.setEnabled(isChecked);
mHandwavePreference.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,145 @@
/*
* 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.content.pm.PackageManager;
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 DozeUtils {
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";
protected static final String GESTURE_HAND_WAVE_KEY = "gesture_hand_wave";
protected static final String GESTURE_POCKET_KEY = "gesture_pocket";
public 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);
}
public static void checkDozeService(Context context) {
if (isDozeEnabled(context) && !isAlwaysOnEnabled(context) && sensorsEnabled(context)) {
startService(context);
} else {
stopService(context);
}
}
protected static boolean getProxCheckBeforePulse(Context context) {
try {
Context con = context.createPackageContext("com.android.systemui", 0);
int id = con.getResources().getIdentifier("doze_proximity_check_before_pulse",
"bool", "com.android.systemui");
return con.getResources().getBoolean(id);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
protected static boolean enableDoze(Context context, boolean enable) {
return Settings.Secure.putInt(context.getContentResolver(),
DOZE_ENABLED, enable ? 1 : 0);
}
public static boolean isDozeEnabled(Context context) {
return Settings.Secure.getInt(context.getContentResolver(),
DOZE_ENABLED, 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) {
final boolean enabledByDefault = context.getResources()
.getBoolean(com.android.internal.R.bool.config_dozeAlwaysOnEnabled);
return Settings.Secure.getIntForUser(context.getContentResolver(),
DOZE_ALWAYS_ON, alwaysOnDisplayAvailable(context) && enabledByDefault ? 1 : 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 isGestureEnabled(context, GESTURE_PICK_UP_KEY);
}
protected static boolean isHandwaveGestureEnabled(Context context) {
return isGestureEnabled(context, GESTURE_HAND_WAVE_KEY);
}
protected static boolean isPocketGestureEnabled(Context context) {
return isGestureEnabled(context, GESTURE_POCKET_KEY);
}
public static boolean sensorsEnabled(Context context) {
return isPickUpEnabled(context) || isHandwaveGestureEnabled(context)
|| isPocketGestureEnabled(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,93 @@
/*
* 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.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 SensorManager mSensorManager;
private Sensor mSensor;
private Context mContext;
private ExecutorService mExecutorService;
private long mEntryTimestamp;
public PickupSensor(Context context) {
mContext = context;
mSensorManager = mContext.getSystemService(SensorManager.class);
mSensor = DozeUtils.getSensor(mSensorManager, "xiaomi.sensor.pickup");
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) {
DozeUtils.launchDozePulse(mContext);
}
}
@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);
mEntryTimestamp = SystemClock.elapsedRealtime();
});
}
protected void disable() {
if (DEBUG) Log.d(TAG, "Disabling");
submit(() -> {
mSensorManager.unregisterListener(this, mSensor);
});
}
}

View File

@ -0,0 +1,107 @@
/*
* 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.util.Log;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ProximitySensor implements SensorEventListener {
private static final boolean DEBUG = false;
private static final String TAG = "ProximitySensor";
// Maximum time for the hand to cover the sensor: 1s
private static final int HANDWAVE_MAX_DELTA_NS = 1000 * 1000 * 1000;
// Minimum time until the device is considered to have been in the pocket: 2s
private static final int POCKET_MIN_DELTA_NS = 2000 * 1000 * 1000;
private SensorManager mSensorManager;
private Sensor mSensor;
private Context mContext;
private ExecutorService mExecutorService;
private boolean mSawNear = false;
private long mInPocketTime = 0;
public ProximitySensor(Context context) {
mContext = context;
mSensorManager = mContext.getSystemService(SensorManager.class);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY, false);
mExecutorService = Executors.newSingleThreadExecutor();
}
private Future<?> submit(Runnable runnable) {
return mExecutorService.submit(runnable);
}
@Override
public void onSensorChanged(SensorEvent event) {
boolean isNear = event.values[0] < mSensor.getMaximumRange();
if (mSawNear && !isNear) {
if (shouldPulse(event.timestamp)) {
DozeUtils.launchDozePulse(mContext);
}
} else {
mInPocketTime = event.timestamp;
}
mSawNear = isNear;
}
private boolean shouldPulse(long timestamp) {
long delta = timestamp - mInPocketTime;
if (DozeUtils.isHandwaveGestureEnabled(mContext) &&
DozeUtils.isPocketGestureEnabled(mContext)) {
return true;
} else if (DozeUtils.isHandwaveGestureEnabled(mContext)) {
return delta < HANDWAVE_MAX_DELTA_NS;
} else if (DozeUtils.isPocketGestureEnabled(mContext)) {
return delta >= POCKET_MIN_DELTA_NS;
}
return false;
}
@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);
});
}
}