diff options
| author | Jason Riordan <jriordan001@gmail.com> | 2017-03-02 22:36:31 -0500 |
|---|---|---|
| committer | Jason Riordan <jriordan001@gmail.com> | 2017-03-02 22:36:31 -0500 |
| commit | f2354088550d90a33c9c95aabcceadf84b4951ab (patch) | |
| tree | b5b344d5e7711f7af4fe7cca02e3a2d596b1f504 /doze | |
| parent | 8270b988871fa24ef5ed35b52b68fb4e213cfe8a (diff) | |
mofd: return of the doze
Change-Id: I3884d2df6413177a1a256087f665964997cb38b8
Diffstat (limited to 'doze')
| -rw-r--r-- | doze/Android.mk | 41 | ||||
| -rw-r--r-- | doze/AndroidManifest.xml | 52 | ||||
| -rw-r--r-- | doze/proguard.flags | 8 | ||||
| -rw-r--r-- | doze/res/drawable/ic_settings_doze.xml | 51 | ||||
| -rw-r--r-- | doze/res/drawable/switchbar_background.xml | 17 | ||||
| -rw-r--r-- | doze/res/layout/doze.xml | 27 | ||||
| -rw-r--r-- | doze/res/layout/switch_bar.xml | 45 | ||||
| -rw-r--r-- | doze/res/values/colors.xml | 25 | ||||
| -rw-r--r-- | doze/res/values/dimens.xml | 20 | ||||
| -rw-r--r-- | doze/res/values/styles.xml | 34 | ||||
| -rw-r--r-- | doze/res/xml/doze_settings.xml | 43 | ||||
| -rw-r--r-- | doze/src/com/cyanogenmod/settings/doze/BootCompletedReceiver.java | 33 | ||||
| -rw-r--r-- | doze/src/com/cyanogenmod/settings/doze/DozeSettings.java | 45 | ||||
| -rw-r--r-- | doze/src/com/cyanogenmod/settings/doze/DozeSettingsFragment.java | 141 | ||||
| -rw-r--r-- | doze/src/com/cyanogenmod/settings/doze/OrientationSensor.java | 150 | ||||
| -rw-r--r-- | doze/src/com/cyanogenmod/settings/doze/PickUpSensor.java | 120 | ||||
| -rw-r--r-- | doze/src/com/cyanogenmod/settings/doze/ProximitySensor.java | 99 | ||||
| -rw-r--r-- | doze/src/com/cyanogenmod/settings/doze/SensorsDozeService.java | 438 |
18 files changed, 1389 insertions, 0 deletions
diff --git a/doze/Android.mk b/doze/Android.mk new file mode 100644 index 0000000..43c008a --- /dev/null +++ b/doze/Android.mk @@ -0,0 +1,41 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := ZenfoneDoze +LOCAL_CERTIFICATE := platform +LOCAL_PRIVILEGED_MODULE := true + +LOCAL_STATIC_JAVA_LIBRARIES := \ + android-support-v14-preference \ + android-support-v7-appcompat \ + android-support-v7-preference \ + android-support-v7-recyclerview \ + org.cyanogenmod.platform.internal + +LOCAL_PROGUARD_FLAG_FILES := proguard.flags + +LOCAL_RESOURCE_DIR := \ + $(LOCAL_PATH)/res \ + $(LOCAL_PATH)/../../../../packages/resources/devicesettings/res\ + frameworks/support/v14/preference/res \ + frameworks/support/v7/appcompat/res \ + frameworks/support/v7/preference/res \ + frameworks/support/v7/recyclerview/res + +LOCAL_AAPT_FLAGS := --auto-add-overlay \ + --extra-packages android.support.v14.preference:android.support.v7.appcompat:android.support.v7.preference:android.support.v7.recyclerview + +ifneq ($(INCREMENTAL_BUILDS),) + LOCAL_PROGUARD_ENABLED := disabled + LOCAL_JACK_ENABLED := incremental +endif + +include frameworks/base/packages/SettingsLib/common.mk + +include $(BUILD_PACKAGE) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/doze/AndroidManifest.xml b/doze/AndroidManifest.xml new file mode 100644 index 0000000..a2328cd --- /dev/null +++ b/doze/AndroidManifest.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.cyanogenmod.settings.doze" + android:versionCode="1" + android:versionName="1.0" + android:sharedUserId="android.uid.system" + > + + <uses-permission android:name="android.permission.DEVICE_POWER" /> + <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="23" + android:targetSdkVersion="23" /> + + <application + android:allowBackup="true" + android:persistent="true" > + + <receiver android:name="com.cyanogenmod.settings.doze.BootCompletedReceiver"> + <intent-filter> + <action android:name="android.intent.action.BOOT_COMPLETED" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </receiver> + + <service android:name="com.cyanogenmod.settings.doze.SensorsDozeService" + android:permission="SensorsDozeService"> + </service> + + <activity + android:name=".DozeSettings" + android:label="@string/ambient_display_title" + android:theme="@style/DozeSettings"> + <intent-filter> + <action android:name="org.cyanogenmod.settings.device.DOZE_SETTINGS" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <meta-data + android:name="org.cyanogenmod.settings.summary.receiver" + android:value="com.cyanogenmod.settings.doze.DozeReceiver" /> + <meta-data + android:name="org.cyanogenmod.settings.summary.key" + android:value="doze_device_settings" /> + </activity> + + </application> + +</manifest> diff --git a/doze/proguard.flags b/doze/proguard.flags new file mode 100644 index 0000000..0b0a8b3 --- /dev/null +++ b/doze/proguard.flags @@ -0,0 +1,8 @@ +-keepclasseswithmembers class * { + public <init>(android.content.Context, android.util.AttributeSet); +} + +-keep class ** extends android.support.v14.preference.PreferenceFragment +-keep class com.cyanogenmod.settings.doze.* { + *; +}
\ No newline at end of file diff --git a/doze/res/drawable/ic_settings_doze.xml b/doze/res/drawable/ic_settings_doze.xml new file mode 100644 index 0000000..4b9bdc9 --- /dev/null +++ b/doze/res/drawable/ic_settings_doze.xml @@ -0,0 +1,51 @@ +<!-- + Copyright (C) 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="64dp" + android:height="64dp" + android:viewportWidth="64" + android:viewportHeight="64"> + + <group + android:translateY="-988.583"> + <path + android:fillColor="@android:color/white" + android:pathData="M15.0133 +1051.24c-1.3615-0.2479-2.37425-1.2789-2.57968-2.6262-0.06554-0.4298-0.06571-55.8484-0.00018-56.28 +0.09875-0.65024 0.367851-1.20544 0.812983-1.6773 0.402211-0.42637 +0.920053-0.7356 1.49909-0.8952l0.299302-0.0825h16.845 16.845l0.291174 +0.0804c1.24697 0.34447 2.13039 1.32473 2.32019 2.57456 0.06515 0.42898 0.06541 +55.8484 0.0003 56.28-0.188067 1.2461-1.07608 2.2305-2.32306 2.5752l-0.288567 +0.08h-16.755c-13.5267 0-16.7958 +0-16.9665-0.034zm29.8065-31.1862v-19.23h-12.99-12.99v19.23 19.23h12.99 +12.99v-19.23zm-13.459 +11.687c-1.03547-0.2354-1.77837-1.1208-1.83292-2.1845l-0.01654-0.3225h1.87175c1.02946 +0 2.10645 0.01 2.3933 0.02l0.521553 0.02-0.01945 0.253c-0.02847 0.3705-0.09559 +0.6134-0.267159 0.9672-0.135477 0.2794-0.18522 0.3474-0.439626 0.6013-0.31197 +0.3114-0.571617 0.4707-0.976866 0.5995-0.269196 0.085-0.949163 0.111-1.23404 +0.046zm-9.04096-4.1842v-0.6872l1.10534-1.0831 1.10534-1.0831 +0.02483-1.2072c0.01366-0.664 0.02781-2.213 0.03145-3.4422 0.007-2.3727 +0.01776-2.5909 0.162279-3.3 0.234013-1.1483 0.861931-2.2993 1.7263-3.1643 +0.762874-0.7634 1.91951-1.4813 3.00204-1.8633 0.262572-0.093 0.512691-0.1813 +0.555819-0.1969l0.07842-0.029 0.01577-0.426c0.01284-0.3469 0.03018-0.4706 +0.09332-0.666 0.197394-0.6109 0.642609-1.0525 1.21018-1.2004 0.365688-0.095 +0.860153-0.043 1.2089 0.1282 0.234414 0.1149 0.589851 0.4783 0.725931 0.7422 +0.171483 0.3325 0.207933 0.491 0.225975 0.9825 0.01148 0.3126 0.02671 0.4425 +0.0519 0.4425 0.01961 0 0.2844 0.088 0.588423 0.1954 2.74734 0.9715 4.21726 +2.7794 4.71985 5.805 0.171696 1.0336 0.211308 1.7926 0.259098 4.9646l0.03345 +2.22 1.10911 1.095 1.1091 1.095-0.0014 0.6825-0.0014 0.6825h-9.57-9.57v-0.6872z" /> + </group> +</vector>
\ No newline at end of file diff --git a/doze/res/drawable/switchbar_background.xml b/doze/res/drawable/switchbar_background.xml new file mode 100644 index 0000000..7fd9316 --- /dev/null +++ b/doze/res/drawable/switchbar_background.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 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. +--> + +<ripple xmlns:android="http://schemas.android.com/apk/res/android" + android:color="?android:attr/colorControlHighlight"> + <item android:drawable="@color/switch_bar_background" /> +</ripple> diff --git a/doze/res/layout/doze.xml b/doze/res/layout/doze.xml new file mode 100644 index 0000000..e3fa240 --- /dev/null +++ b/doze/res/layout/doze.xml @@ -0,0 +1,27 @@ +<?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> diff --git a/doze/res/layout/switch_bar.xml b/doze/res/layout/switch_bar.xml new file mode 100644 index 0000000..2d171c4 --- /dev/null +++ b/doze/res/layout/switch_bar.xml @@ -0,0 +1,45 @@ +<?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"> + + <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="48dp" + android:maxLines="2" + android:ellipsize="end" + android:textAppearance="@android:style/TextAppearance.Material.Title" + android:textColor="?android:attr/textColorPrimaryInverse" + android:textAlignment="viewStart" + android:text="@string/switch_bar_on" /> + + <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/ThemeOverlay.SwitchBar" /> + +</LinearLayout>
\ No newline at end of file diff --git a/doze/res/values/colors.xml b/doze/res/values/colors.xml new file mode 100644 index 0000000..407eb9d --- /dev/null +++ b/doze/res/values/colors.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The CyanogenMod 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> + <!-- Palette colors referenced by top-level themes. --> + <color name="theme_primary">#ff263238</color> + <color name="theme_primary_dark">#ff21272b</color> + <color name="theme_accent">#ff009688</color> + <color name="switch_bar_background">#ff37474f</color> + <color name="switch_accent_color">#ff7fcac3</color> + <color name="system_secondary_color">#ff37474F</color> +</resources> diff --git a/doze/res/values/dimens.xml b/doze/res/values/dimens.xml new file mode 100644 index 0000000..133701d --- /dev/null +++ b/doze/res/values/dimens.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The CyanogenMod 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> + <!-- ActionBar contentInsetStart --> + <dimen name="actionbar_subsettings_contentInsetStart">72dp</dimen> +</resources> diff --git a/doze/res/values/styles.xml b/doze/res/values/styles.xml new file mode 100644 index 0000000..bfb5b4f --- /dev/null +++ b/doze/res/values/styles.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2016 The CyanogenMod 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="DozeSettings" parent="@android:style/Theme.Material.Settings"> + <item name="android:windowActionBar">false</item> + <item name="preferenceTheme">@style/DozePreferenceTheme</item> + </style> + + <style name="DozePreferenceTheme" parent="@android:style/Theme.Material.Settings"> + <item name="dropdownPreferenceStyle">@style/Preference.DropDown.Material</item> + </style> + + <style name="ThemeOverlay.SwitchBar" parent="@android:style/ThemeOverlay"> + <item name="android:colorAccent">@color/switch_accent_color</item> + </style> + + <style name="ThemeOverlay.SwitchBar.Secondary" parent="@android:style/ThemeOverlay"> + <item name="android:colorAccent">@color/system_secondary_color</item> + </style> +</resources> diff --git a/doze/res/xml/doze_settings.xml b/doze/res/xml/doze_settings.xml new file mode 100644 index 0000000..0797695 --- /dev/null +++ b/doze/res/xml/doze_settings.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The CyanogenMod Project + Copyright (C) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License" + you may not use this file except in compliance with the License. + 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"> + + <PreferenceCategory + android:title="@string/screen_gestures_panel_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_pick_up" + android:defaultValue="false" + android:title="@string/pick_up_gesture_title" + android:summary="@string/pick_up_gesture_summary" /> + + <SwitchPreference + android:key="gesture_pocket" + android:defaultValue="false" + android:title="@string/pocket_gesture_title" + android:summary="@string/pocket_gesture_summary" /> + + </PreferenceCategory> + +</PreferenceScreen> diff --git a/doze/src/com/cyanogenmod/settings/doze/BootCompletedReceiver.java b/doze/src/com/cyanogenmod/settings/doze/BootCompletedReceiver.java new file mode 100644 index 0000000..743fe8b --- /dev/null +++ b/doze/src/com/cyanogenmod/settings/doze/BootCompletedReceiver.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015 The CyanogenMod Project + * Copyright (c) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.cyanogenmod.settings.doze; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +public class BootCompletedReceiver extends BroadcastReceiver { + static final String TAG = "KiwiDoze"; + + @Override + public void onReceive(final Context context, Intent intent) { + Log.d(TAG, "Booting"); + context.startService(new Intent(context, SensorsDozeService.class)); + } +} diff --git a/doze/src/com/cyanogenmod/settings/doze/DozeSettings.java b/doze/src/com/cyanogenmod/settings/doze/DozeSettings.java new file mode 100644 index 0000000..36bfb16 --- /dev/null +++ b/doze/src/com/cyanogenmod/settings/doze/DozeSettings.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016 The CyanogenMod Project + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.cyanogenmod.settings.doze; + +import android.os.Bundle; +import android.view.MenuItem; + +import com.android.settingslib.drawer.SettingsDrawerActivity; + +public class DozeSettings extends SettingsDrawerActivity { + + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.doze); + + getFragmentManager().beginTransaction().replace(R.id.content_frame, + new DozeSettingsFragment()).commit(); + + getActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + onBackPressed(); + return true; + } + return false; + } +} diff --git a/doze/src/com/cyanogenmod/settings/doze/DozeSettingsFragment.java b/doze/src/com/cyanogenmod/settings/doze/DozeSettingsFragment.java new file mode 100644 index 0000000..9579567 --- /dev/null +++ b/doze/src/com/cyanogenmod/settings/doze/DozeSettingsFragment.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2015-2016 The CyanogenMod Project + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.cyanogenmod.settings.doze; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.provider.Settings; +import android.support.v14.preference.PreferenceFragment; +import android.support.v14.preference.SwitchPreference; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; +import android.widget.Switch; + +public class DozeSettingsFragment extends PreferenceFragment implements + CompoundButton.OnCheckedChangeListener { + + private static final String KEY_GESTURE_HAND_WAVE = "gesture_hand_wave"; + private static final String KEY_GESTURE_PICK_UP = "gesture_pick_up"; + private static final String KEY_GESTURE_POCKET = "gesture_pocket"; + + private Switch mSwitch; + private SwitchPreference mHandwavePreference; + private SwitchPreference mPickupPreference; + private SwitchPreference mPocketPreference; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.doze_settings); + + SharedPreferences prefs = getActivity().getSharedPreferences("doze_settings", + Activity.MODE_PRIVATE); + if (savedInstanceState == null && !prefs.getBoolean("first_help_shown", false)) { + showHelp(); + } + + boolean dozeEnabled = isDozeEnabled(); + + mHandwavePreference = (SwitchPreference) findPreference(KEY_GESTURE_HAND_WAVE); + mHandwavePreference.setEnabled(dozeEnabled); + mPickupPreference = (SwitchPreference) findPreference(KEY_GESTURE_PICK_UP); + mPickupPreference.setEnabled(dozeEnabled); + mPocketPreference = (SwitchPreference) findPreference(KEY_GESTURE_POCKET); + mPocketPreference.setEnabled(dozeEnabled); + } + + @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); + + View switchBar = view.findViewById(R.id.switch_bar); + mSwitch = (Switch) switchBar.findViewById(android.R.id.switch_widget); + mSwitch.setChecked(isDozeEnabled()); + mSwitch.setOnCheckedChangeListener(this); + + switchBar.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mSwitch.setChecked(!mSwitch.isChecked()); + } + }); + } + + private boolean enableDoze(boolean enable) { + return Settings.Secure.putInt(getContext().getContentResolver(), + Settings.Secure.DOZE_ENABLED, enable ? 1 : 0); + } + + private boolean isDozeEnabled() { + return Settings.Secure.getInt(getContext().getContentResolver(), + Settings.Secure.DOZE_ENABLED, 1) != 0; + } + + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + boolean ret = enableDoze(b); + if (ret) { + mHandwavePreference.setEnabled(b); + mPickupPreference.setEnabled(b); + mPocketPreference.setEnabled(b); + } + } + + public 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, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int 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"); + } +} diff --git a/doze/src/com/cyanogenmod/settings/doze/OrientationSensor.java b/doze/src/com/cyanogenmod/settings/doze/OrientationSensor.java new file mode 100644 index 0000000..afaaa72 --- /dev/null +++ b/doze/src/com/cyanogenmod/settings/doze/OrientationSensor.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2015 The CyanogenMod Project + * Copyright (c) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.cyanogenmod.settings.doze; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + +public class OrientationSensor implements SensorEventListener { + + public static final int ORIENTATION_UNKNOWN = 0; + public static final int ORIENTATION_FACE_DOWN = 1; + public static final int ORIENTATION_FACE_UP = 2; + public static final int ORIENTATION_VERTICAL = 3; + + private static final int ORIENTATION_DELAY = 60 * 1000; + private static final int ORIENTATION_LATENCY = 0; + private static final float MATH_PI_1_4 = 0.785398F; + private static final float MATH_PI_3_4 = 2.35619F; + + private boolean mEnabled; + private boolean mReady; + private int mState; + private float mGravity[]; + private float mMagnetic[]; + private OrientationListener mOrientationListener; + private Sensor mAccelerometerSensor; + private Sensor mMagneticFieldSensor; + private SensorManager mSensorManager; + + public interface OrientationListener { + void onEvent(); + } + + public boolean isFaceDown() { + return mReady && mState == ORIENTATION_FACE_DOWN; + } + + public boolean isFaceUp() { + return mReady && mState == ORIENTATION_FACE_UP; + } + + public boolean isVertical() { + return mReady && mState == ORIENTATION_VERTICAL; + } + + public OrientationSensor(Context context, SensorManager sensorManager, + OrientationListener orientationListener) { + mEnabled = false; + reset(); + mAccelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER, false); + mMagneticFieldSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD, false); + + mOrientationListener = orientationListener; + mSensorManager = sensorManager; + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + } + + public void onSensorChanged(SensorEvent event) { + if (event.values.length == 0) return; + + switch (event.sensor.getType()) { + case Sensor.TYPE_ACCELEROMETER: + mGravity = event.values; + break; + case Sensor.TYPE_MAGNETIC_FIELD: + mMagnetic = event.values; + break; + default: + break; + } + + if (mGravity != null && mMagnetic != null) { + float[] rotationMatrix = new float[9]; + if (SensorManager.getRotationMatrix(rotationMatrix, new float[9], mGravity, mMagnetic)) + { + float[] values = new float[3]; + mState = ORIENTATION_UNKNOWN; + SensorManager.getOrientation(rotationMatrix, values); + + // Orientation is flat + if (values[1] > -MATH_PI_1_4 && values[1] < MATH_PI_1_4) { + // Device is face up + if (values[2] > -MATH_PI_1_4 && values[2] < MATH_PI_1_4) { + mState = ORIENTATION_FACE_UP; + } + // Device is face down + else if (values[2] < -MATH_PI_3_4 || values[2] > MATH_PI_3_4) { + mState = ORIENTATION_FACE_DOWN; + } + } + // Orientation is vertical + if (values[1] < -MATH_PI_1_4 || values[1] > MATH_PI_1_4 || + (values[2] > MATH_PI_1_4 && values[2] < MATH_PI_3_4) || + (values[2] > -MATH_PI_3_4 && values[2] < -MATH_PI_1_4)) { + mState = ORIENTATION_VERTICAL; + } + + // Launch an event + mReady = true; + mOrientationListener.onEvent(); + } + } + } + + public void enable() { + if (!mEnabled && mAccelerometerSensor != null && mMagneticFieldSensor != null) { + reset(); + mState = ORIENTATION_UNKNOWN; + mSensorManager.registerListener(this, mAccelerometerSensor, + ORIENTATION_DELAY, ORIENTATION_LATENCY); + mSensorManager.registerListener(this, mMagneticFieldSensor, + ORIENTATION_DELAY, ORIENTATION_LATENCY); + mEnabled = true; + } + } + + public void reset() { + mGravity = null; + mMagnetic = null; + mReady = false; + } + + public void disable() { + if (mEnabled && mAccelerometerSensor != null && mMagneticFieldSensor != null) { + mSensorManager.unregisterListener(this,mAccelerometerSensor); + mSensorManager.unregisterListener(this, mMagneticFieldSensor); + mEnabled = false; + } + } +} diff --git a/doze/src/com/cyanogenmod/settings/doze/PickUpSensor.java b/doze/src/com/cyanogenmod/settings/doze/PickUpSensor.java new file mode 100644 index 0000000..af780aa --- /dev/null +++ b/doze/src/com/cyanogenmod/settings/doze/PickUpSensor.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015 The CyanogenMod Project + * Copyright (c) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.cyanogenmod.settings.doze; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + +public class PickUpSensor implements SensorEventListener { + + public static final int PICK_UP_UNKNOWN = 0; + public static final int PICK_UP_FALSE = 1; + public static final int PICK_UP_TRUE = 2; + + private static final int PICKUP_DELAY = 500 * 1000; + private static final int PICKUP_LATENCY = 100 * 1000; + private static final float PICK_UP_SAFEZONE = 5; + private static final float PICK_UP_THRESHOLD = 6; + + private boolean mEnabled; + private boolean mReady; + private int mState; + private Sensor mPickUpSensor; + private PickUpListener mPickUpListener; + private SensorManager mSensorManager; + + public interface PickUpListener { + void onEvent(); + void onInit(); + } + + public boolean isPickedUp() { + return mReady && mState == PICK_UP_TRUE; + } + + public PickUpSensor(Context context, SensorManager sensorManager, + PickUpListener pickUpListener) { + mEnabled = false; + reset(); + mPickUpSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER, false); + mPickUpListener = pickUpListener; + mSensorManager = sensorManager; + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + } + + public void onSensorChanged(SensorEvent event) { + if (event.values.length == 0) return; + float x = event.values[0]; + float y = event.values[1]; + float z = event.values[2]; + + // Device is picked-up + if (isPickUpAbove(x, y, PICK_UP_SAFEZONE)) { + if (isPickUpAbove(x, y, PICK_UP_THRESHOLD)) { + if (mState != PICK_UP_TRUE) { + mState = PICK_UP_TRUE; + if (mReady) { + mPickUpListener.onEvent(); + } + } + } + } + // Device is put down + else if (mState != PICK_UP_FALSE) { + mState = PICK_UP_FALSE; + if (mReady) { + mPickUpListener.onEvent(); + } + } + + // Init the sensor + if (!mReady) { + mReady = true; + mPickUpListener.onInit(); + } + } + + public boolean isPickUpAbove(float x, float y, float threshold) { + return (x < -threshold || x > threshold || y > threshold); + } + + public void enable() { + if (!mEnabled && mPickUpSensor != null) { + reset(); + mSensorManager.registerListener(this, mPickUpSensor, PICKUP_DELAY, PICKUP_LATENCY); + mEnabled = true; + } + } + + public void reset() { + mReady = false; + mState = PICK_UP_UNKNOWN; + } + + public void disable() { + if (mEnabled && mPickUpSensor != null) { + mSensorManager.unregisterListener(this, mPickUpSensor); + mEnabled = false; + } + } +} diff --git a/doze/src/com/cyanogenmod/settings/doze/ProximitySensor.java b/doze/src/com/cyanogenmod/settings/doze/ProximitySensor.java new file mode 100644 index 0000000..c02347b --- /dev/null +++ b/doze/src/com/cyanogenmod/settings/doze/ProximitySensor.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2015 The CyanogenMod Project + * Copyright (c) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.cyanogenmod.settings.doze; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; + +public class ProximitySensor implements SensorEventListener { + + private static final int PROXIMITY_DELAY = 1000 * 1000; + private static final int PROXIMITY_LATENCY = 100 * 1000; + + private boolean mEnabled; + private boolean mReady; + private boolean mState; + private float mMaxRange; + private ProximityListener mProximityListener; + private Sensor mProximitySensor; + private SensorManager mSensorManager; + + public interface ProximityListener { + void onEvent(boolean isNear, long timestamp); + void onInit(boolean isNear, long timestamp); + } + + public ProximitySensor(Context context, SensorManager sensorManager, + ProximityListener proximitylistener) { + mEnabled = false; + reset(); + mProximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY, true); + + mProximityListener = proximitylistener; + mSensorManager = sensorManager; + + if (mProximitySensor != null) { + mMaxRange = mProximitySensor.getMaximumRange(); + } + } + + public void onAccuracyChanged(Sensor sensor, int accuracy) { + } + + public void onSensorChanged(SensorEvent event) { + if (event.values.length == 0) return; + boolean isNear = (event.values[0] < mMaxRange); + + // Launch an event + if (mState != isNear) { + mState = isNear; + if (mReady) { + mProximityListener.onEvent(mState, event.timestamp); + } + } + + // Init the sensor + if (!mReady) { + mProximityListener.onInit(mState, event.timestamp); + mReady = true; + } + } + + public void enable() { + if (!mEnabled && mProximitySensor != null) { + mSensorManager.registerListener(this, mProximitySensor, PROXIMITY_DELAY, + PROXIMITY_LATENCY); + mEnabled = true; + } + } + + public void reset() { + mReady = false; + mState = false; + } + + public void disable() { + if (mEnabled && mProximitySensor != null) { + mSensorManager.unregisterListener(this, mProximitySensor); + mEnabled = false; + } + } +} diff --git a/doze/src/com/cyanogenmod/settings/doze/SensorsDozeService.java b/doze/src/com/cyanogenmod/settings/doze/SensorsDozeService.java new file mode 100644 index 0000000..00f4121 --- /dev/null +++ b/doze/src/com/cyanogenmod/settings/doze/SensorsDozeService.java @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2015 The CyanogenMod Project + * Copyright (c) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.cyanogenmod.settings.doze; + +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.hardware.SensorManager; +import android.media.AudioManager; +import android.os.IBinder; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.os.SystemClock; +import android.os.UserHandle; +import android.os.Vibrator; +import android.preference.PreferenceManager; +import android.provider.Settings; +import android.util.Log; + +import cyanogenmod.providers.CMSettings; + +public class SensorsDozeService extends Service { + + public static final boolean DEBUG = false; + public static final String TAG = "SensorsDozeService"; + + private static final String DOZE_INTENT = "com.android.systemui.doze.pulse"; + + private static final int HANDWAVE_DELTA_NS = 1000 * 1000 * 1000; + private static final int PULSE_MIN_INTERVAL_MS = 5000; + private static final int SENSORS_WAKELOCK_DURATION = 1000; + private static final int VIBRATOR_ACKNOWLEDGE = 40; + + private static final String KEY_GESTURE_HAND_WAVE = "gesture_hand_wave"; + private static final String KEY_GESTURE_PICK_UP = "gesture_pick_up"; + private static final String KEY_GESTURE_POCKET = "gesture_pocket"; + + private Context mContext; + private OrientationSensor mOrientationSensor; + private PickUpSensor mPickUpSensor; + private PowerManager mPowerManager; + private ProximitySensor mProximitySensor; + private WakeLock mSensorsWakeLock; + + private boolean mDozeEnabled; + private boolean mHandwaveDoze; + private boolean mHandwaveGestureEnabled; + private boolean mPickUpDoze; + private boolean mPickUpGestureEnabled; + private boolean mPickUpState; + private boolean mPocketDoze; + private boolean mPocketGestureEnabled; + private boolean mProximityNear; + private long mLastPulseTimestamp; + private long mLastStowedTimestamp; + + private OrientationSensor.OrientationListener mOrientationListener = + new OrientationSensor.OrientationListener() { + public void onEvent() { + setOrientationSensor(false, false); + handleOrientation(); + } + }; + + private PickUpSensor.PickUpListener mPickUpListener = + new PickUpSensor.PickUpListener() { + public void onEvent() { + mPickUpState = mPickUpSensor.isPickedUp(); + handlePickUp(); + } + public void onInit() { + mPickUpState = mPickUpSensor.isPickedUp(); + if (DEBUG) Log.d(TAG, "Pick-up sensor init : " + mPickUpState); + } + }; + + private ProximitySensor.ProximityListener mProximityListener = + new ProximitySensor.ProximityListener() { + public void onEvent(boolean isNear, long timestamp) { + mProximityNear = isNear; + handleProximity(timestamp); + } + public void onInit(boolean isNear, long timestamp) { + if (DEBUG) Log.d(TAG, "Proximity sensor init : " + isNear); + mLastStowedTimestamp = timestamp; + mProximityNear = isNear; + + // Pick-up or Orientation sensor initialization + if (!isEventPending() && !isNear && isPickUpEnabled()) { + setPickUpSensor(true, false); + } + } + }; + + public void onCreate() { + if (DEBUG) Log.d(TAG, "Creating service"); + + super.onCreate(); + mContext = this; + + mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + mSensorsWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + TAG + "WakeLock"); + SensorManager sensorManager = (SensorManager) + mContext.getSystemService(Context.SENSOR_SERVICE); + mOrientationSensor = new OrientationSensor(mContext, sensorManager, mOrientationListener); + mPickUpSensor = new PickUpSensor(mContext, sensorManager, mPickUpListener); + mProximitySensor = new ProximitySensor(mContext, sensorManager, mProximityListener); + + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext); + loadPreferences(sharedPrefs); + sharedPrefs.registerOnSharedPreferenceChangeListener(mPrefListener); + } + + public int onStartCommand(Intent intent, int flags, int startId) { + if (DEBUG) Log.d(TAG, "Starting service"); + + IntentFilter intentScreen = new IntentFilter(Intent.ACTION_SCREEN_ON); + intentScreen.addAction(Intent.ACTION_SCREEN_OFF); + mContext.registerReceiver(mScreenStateReceiver, intentScreen); + if (!mPowerManager.isInteractive()) { + onDisplayOff(); + } + + return START_STICKY; + } + + public void onDestroy() { + if (DEBUG) Log.d(TAG, "Destroying service"); + + super.onDestroy(); + setOrientationSensor(false, true); + setPickUpSensor(false, true); + setProximitySensor(false, true); + } + + public IBinder onBind(Intent intent) { + return null; + } + + private void getDozeEnabled() { + boolean enabled = true; + if (android.provider.Settings.Secure.getInt( + mContext.getContentResolver(), Settings.Secure.DOZE_ENABLED, 1) == 0) { + enabled = false; + } + mDozeEnabled = enabled; + } + + private boolean isDozeEnabled() { + return mDozeEnabled; + } + + private boolean isHandwaveEnabled() { + return mHandwaveGestureEnabled && isDozeEnabled(); + } + + private boolean isPickUpEnabled() { + return mPickUpGestureEnabled && isDozeEnabled(); + } + + private boolean isPocketEnabled() { + return mPocketGestureEnabled && isDozeEnabled(); + } + + private boolean isEventPending() { + return mHandwaveDoze || mPickUpDoze || mPocketDoze; + } + + private void handleProximity(long timestamp) { + long delta = timestamp - mLastStowedTimestamp; + boolean quickWave = delta < HANDWAVE_DELTA_NS; + getDozeEnabled(); + if (DEBUG) Log.d(TAG, "Proximity sensor : isNear " + mProximityNear); + + // Proximity sensor released + if (!mProximityNear) { + mHandwaveDoze = false; + mPickUpDoze = false; + mPocketDoze = false; + + // Handwave / Pick-up / Pocket gestures activated + if (isHandwaveEnabled() && isPickUpEnabled() && isPocketEnabled()) { + mHandwaveDoze = quickWave; + mPickUpDoze = !quickWave; + mPocketDoze = !quickWave; + setOrientationSensor(true, false); + } + // Handwave Doze detected + else if (isHandwaveEnabled() && quickWave) { + mHandwaveDoze = true; + setOrientationSensor(true, false); + } + // Pick-up / Pocket Doze detected + else if ((isPickUpEnabled() || isPocketEnabled()) && !quickWave) { + mPickUpDoze = isPickUpEnabled(); + mPocketDoze = isPocketEnabled(); + setOrientationSensor(true, false); + } + // Start the pick-up sensor + else if (isPickUpEnabled()) { + setPickUpSensor(true, false); + } + } + // Proximity sensor stowed + else { + mLastStowedTimestamp = timestamp; + setOrientationSensor(false, false); + setPickUpSensor(false, false); + } + } + + private void handleOrientation() { + if (DEBUG) Log.d(TAG, "Orientation sensor : " + + "FaceDown " + mOrientationSensor.isFaceDown() + + ", FaceUp " + mOrientationSensor.isFaceUp() + + ", Vertical " + mOrientationSensor.isVertical()); + + // Orientation Doze analysis + if (!mProximityNear) { + analyseDoze(); + } + } + + private void handlePickUp() { + getDozeEnabled(); + if (DEBUG) Log.d(TAG, "Pick-up sensor : " + mPickUpState); + + // Pick-up Doze analysis + if (mPickUpState && isPickUpEnabled()) { + mPickUpDoze = true; + launchWakeLock(); + analyseDoze(); + } + // Picked-down + else { + mPickUpDoze = false; + } + } + + private void analyseDoze() { + getDozeEnabled(); + if (DEBUG) + Log.d(TAG, "Doze analysis : HandwaveDoze " + mHandwaveDoze + + ", PickUpDoze " + mPickUpDoze + + ", PocketDoze " + mPocketDoze + + ", PickUpState " + mPickUpState); + + // Handwave Doze launch + if (mHandwaveDoze && !mOrientationSensor.isFaceDown()) { + launchDozePulse(); + } + // Pocket Doze launch + else if (mPickUpDoze && + ((mPickUpState && !mProximityNear) || + (!mPickUpState && mOrientationSensor.isFaceDown()))) { + launchDozePulse(); + } + // Pocket Doze launch + else if (mPocketDoze && mOrientationSensor.isVertical()) { + launchDozePulse(); + } + + // Restore the pick-up sensor + if (!mProximityNear && isPickUpEnabled()) { + setPickUpSensor(true, false); + } + + resetValues(); + } + + private void launchDozePulse() { + long delta; + if (mLastPulseTimestamp != 0) { + delta = SystemClock.elapsedRealtime() - mLastPulseTimestamp; + } else { + delta = PULSE_MIN_INTERVAL_MS; + } + + if (delta >= PULSE_MIN_INTERVAL_MS) { + if (DEBUG) Log.d(TAG, "Doze launch. Time since last : " + delta); + + launchWakeLock(); + launchAcknowledge(); + mLastPulseTimestamp = SystemClock.elapsedRealtime(); + mContext.sendBroadcastAsUser(new Intent(DOZE_INTENT), + UserHandle.ALL); + } + else if (DEBUG) Log.d(TAG, "Doze avoided. Time since last : " + delta); + } + + private void launchWakeLock() { + mSensorsWakeLock.acquire(SENSORS_WAKELOCK_DURATION); + } + + private void launchAcknowledge() { + AudioManager audioManager = (AudioManager) mContext.getSystemService( + Context.AUDIO_SERVICE); + Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); + + boolean enabled = CMSettings.System.getInt(mContext.getContentResolver(), + CMSettings.System.TOUCHSCREEN_GESTURE_HAPTIC_FEEDBACK, 1) != 0; + + switch (audioManager.getRingerMode()) { + case AudioManager.RINGER_MODE_SILENT: + break; + case AudioManager.RINGER_MODE_VIBRATE: + case AudioManager.RINGER_MODE_NORMAL: + default: + if (enabled) { + vibrator.vibrate(VIBRATOR_ACKNOWLEDGE); + } + break; + } + } + + private void resetValues() { + mHandwaveDoze = false; + mPickUpDoze = false; + mPocketDoze = false; + } + + private void setOrientationSensor(boolean enabled, boolean reset) { + if (mOrientationSensor == null) return; + + if (reset) { + mOrientationSensor.reset(); + } + if (enabled) { + setPickUpSensor(false, false); + launchWakeLock(); + mOrientationSensor.enable(); + } else { + mOrientationSensor.disable(); + } + } + + private void setPickUpSensor(boolean enabled, boolean reset) { + if (mPickUpSensor == null) return; + + if (reset) { + mPickUpSensor.reset(); + } + if (enabled) { + setOrientationSensor(false, false); + mPickUpSensor.enable(); + } else { + mPickUpSensor.disable(); + } + } + + private void setProximitySensor(boolean enabled, boolean reset) { + if (mProximitySensor == null) return; + + if (reset) { + mProximitySensor.reset(); + } + if (enabled) { + mProximitySensor.enable(); + } else { + mProximitySensor.disable(); + } + } + + private void onDisplayOn() { + if (DEBUG) Log.d(TAG, "Display on"); + + setOrientationSensor(false, true); + setPickUpSensor(false, true); + setProximitySensor(false, true); + } + + private void onDisplayOff() { + if (DEBUG) Log.d(TAG, "Display off"); + + getDozeEnabled(); + mLastPulseTimestamp = 0; + if (isHandwaveEnabled() || isPickUpEnabled() || isPocketEnabled()) { + resetValues(); + setOrientationSensor(false, true); + setPickUpSensor(false, true); + setProximitySensor(true, true); + } + } + + private void loadPreferences(SharedPreferences sharedPreferences) { + mHandwaveGestureEnabled = sharedPreferences.getBoolean(KEY_GESTURE_HAND_WAVE, false); + mPickUpGestureEnabled = sharedPreferences.getBoolean(KEY_GESTURE_PICK_UP, false); + mPocketGestureEnabled = sharedPreferences.getBoolean(KEY_GESTURE_POCKET, false); + } + + private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { + onDisplayOff(); + } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { + onDisplayOn(); + } + } + }; + + private SharedPreferences.OnSharedPreferenceChangeListener mPrefListener = + new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences + sharedPreferences, String key) { + if (KEY_GESTURE_HAND_WAVE.equals(key)) { + mHandwaveGestureEnabled = sharedPreferences.getBoolean( + KEY_GESTURE_HAND_WAVE, false); + } else if (KEY_GESTURE_PICK_UP.equals(key)) { + mPickUpGestureEnabled = sharedPreferences.getBoolean( + KEY_GESTURE_PICK_UP, false); + } else if (KEY_GESTURE_POCKET.equals(key)) { + mPocketGestureEnabled = sharedPreferences.getBoolean( + KEY_GESTURE_POCKET, false); + } + } + }; +} |
