2 * Copyright (c) 2015 The CyanogenMod Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org
.lineageos
.settings
.doze
;
19 import android
.app
.Service
;
20 import android
.content
.BroadcastReceiver
;
21 import android
.content
.Context
;
22 import android
.content
.Intent
;
23 import android
.content
.IntentFilter
;
24 import android
.content
.SharedPreferences
;
25 import android
.hardware
.Sensor
;
26 import android
.hardware
.SensorEvent
;
27 import android
.hardware
.SensorEventListener
;
28 import android
.hardware
.SensorManager
;
29 import android
.os
.IBinder
;
30 import android
.os
.PowerManager
;
31 import android
.os
.UserHandle
;
32 import android
.preference
.PreferenceManager
;
33 import android
.provider
.Settings
;
34 import android
.util
.Log
;
36 import java
.lang
.System
;
37 import java
.util
.ArrayList
;
38 import java
.util
.concurrent
.TimeUnit
;
39 import java
.util
.List
;
41 public class SamsungDozeService
extends Service
{
42 private static final String TAG
= "SamsungDozeService";
43 private static final boolean DEBUG
= false;
45 private static final String DOZE_INTENT
= "com.android.systemui.doze.pulse";
47 private static final String GESTURE_HAND_WAVE_KEY
= "gesture_hand_wave";
48 private static final String GESTURE_POCKET_KEY
= "gesture_pocket";
49 private static final String PROXIMITY_WAKE_KEY
= "proximity_wake_enable";
51 private static final int POCKET_DELTA_NS
= 1000 * 1000 * 1000;
53 private Context mContext
;
54 private SamsungProximitySensor mSensor
;
55 private PowerManager mPowerManager
;
57 private boolean mHandwaveGestureEnabled
= false;
58 private boolean mPocketGestureEnabled
= false;
59 private boolean mProximityWakeEnabled
= false;
61 class SamsungProximitySensor
implements SensorEventListener
{
62 private SensorManager mSensorManager
;
63 private Sensor mSensor
;
65 private boolean mSawNear
= false;
66 private long mInPocketTime
= 0;
68 public SamsungProximitySensor(Context context
) {
69 mSensorManager
= (SensorManager
)context
.getSystemService(Context
.SENSOR_SERVICE
);
70 mSensor
= mSensorManager
.getDefaultSensor(Sensor
.TYPE_PROXIMITY
);
74 public void onSensorChanged(SensorEvent event
) {
75 boolean isNear
= event
.values
[0] < mSensor
.getMaximumRange();
76 if (mSawNear
&& !isNear
) {
77 if (shouldPulse(event
.timestamp
)) {
81 mInPocketTime
= event
.timestamp
;
87 public void onAccuracyChanged(Sensor sensor
, int accuracy
) {
91 private boolean shouldPulse(long timestamp
) {
92 long delta
= timestamp
- mInPocketTime
;
94 if (mHandwaveGestureEnabled
&& mPocketGestureEnabled
) {
96 } else if (mProximityWakeEnabled
&& (delta
< POCKET_DELTA_NS
)) {
97 mPowerManager
.wakeUp(TimeUnit
.NANOSECONDS
.toMillis(System
.nanoTime()));
99 } else if (mHandwaveGestureEnabled
&& !mPocketGestureEnabled
) {
100 return delta
< POCKET_DELTA_NS
;
101 } else if (!mHandwaveGestureEnabled
&& mPocketGestureEnabled
) {
102 return delta
>= POCKET_DELTA_NS
;
107 public void testAndEnable() {
108 if ((isDozeEnabled() && (mHandwaveGestureEnabled
|| mPocketGestureEnabled
)) ||
109 mProximityWakeEnabled
) {
110 mSensorManager
.registerListener(this, mSensor
, SensorManager
.SENSOR_DELAY_NORMAL
);
114 public void disable() {
115 mSensorManager
.unregisterListener(this, mSensor
);
120 public void onCreate() {
121 if (DEBUG
) Log
.d(TAG
, "SamsungDozeService Started");
123 mPowerManager
= (PowerManager
)getSystemService(Context
.POWER_SERVICE
);
124 mSensor
= new SamsungProximitySensor(mContext
);
125 SharedPreferences sharedPrefs
= PreferenceManager
.getDefaultSharedPreferences(mContext
);
126 loadPreferences(sharedPrefs
);
127 sharedPrefs
.registerOnSharedPreferenceChangeListener(mPrefListener
);
128 if (!isInteractive()) {
129 mSensor
.testAndEnable();
134 public int onStartCommand(Intent intent
, int flags
, int startId
) {
135 if (DEBUG
) Log
.d(TAG
, "Starting service");
136 IntentFilter screenStateFilter
= new IntentFilter(Intent
.ACTION_SCREEN_ON
);
137 screenStateFilter
.addAction(Intent
.ACTION_SCREEN_OFF
);
138 mContext
.registerReceiver(mScreenStateReceiver
, screenStateFilter
);
143 public IBinder
onBind(Intent intent
) {
147 private void launchDozePulse() {
148 mContext
.sendBroadcastAsUser(new Intent(DOZE_INTENT
),
149 new UserHandle(UserHandle
.USER_CURRENT
));
152 private boolean isInteractive() {
153 return mPowerManager
.isInteractive();
156 private boolean isDozeEnabled() {
157 return Settings
.Secure
.getInt(mContext
.getContentResolver(),
158 Settings
.Secure
.DOZE_ENABLED
, 1) != 0;
161 private void onDisplayOn() {
162 if (DEBUG
) Log
.d(TAG
, "Display on");
166 private void onDisplayOff() {
167 if (DEBUG
) Log
.d(TAG
, "Display off");
168 mSensor
.testAndEnable();
171 private void loadPreferences(SharedPreferences sharedPreferences
) {
172 mHandwaveGestureEnabled
= sharedPreferences
.getBoolean(GESTURE_HAND_WAVE_KEY
, false);
173 mPocketGestureEnabled
= sharedPreferences
.getBoolean(GESTURE_POCKET_KEY
, false);
174 mProximityWakeEnabled
= sharedPreferences
.getBoolean(PROXIMITY_WAKE_KEY
, false);
177 private BroadcastReceiver mScreenStateReceiver
= new BroadcastReceiver() {
179 public void onReceive(Context context
, Intent intent
) {
180 if (intent
.getAction().equals(Intent
.ACTION_SCREEN_OFF
)) {
182 } else if (intent
.getAction().equals(Intent
.ACTION_SCREEN_ON
)) {
188 private SharedPreferences
.OnSharedPreferenceChangeListener mPrefListener
=
189 new SharedPreferences
.OnSharedPreferenceChangeListener() {
191 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences
, String key
) {
192 if (GESTURE_HAND_WAVE_KEY
.equals(key
)) {
193 mHandwaveGestureEnabled
= sharedPreferences
.getBoolean(GESTURE_HAND_WAVE_KEY
, false);
194 } else if (GESTURE_POCKET_KEY
.equals(key
)) {
195 mPocketGestureEnabled
= sharedPreferences
.getBoolean(GESTURE_POCKET_KEY
, false);
196 } else if (PROXIMITY_WAKE_KEY
.equals(key
)) {
197 mProximityWakeEnabled
= sharedPreferences
.getBoolean(PROXIMITY_WAKE_KEY
, false);