diff options
author | Wilhelm Fitzpatrick <rafial@cyngn.com> | 2015-12-23 15:58:25 -0800 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2018-02-11 02:36:11 +0200 |
commit | 1bd7a90878d1b580f68f32a4afa7df84b8a7e40c (patch) | |
tree | a74eea35178afb2f6c2efd031b2939292f8490f8 | |
parent | 281ea21da6620b7657d24cb28a5c393bb4e81017 (diff) | |
download | android_packages_apps_DeskClock-1bd7a90878d1b580f68f32a4afa7df84b8a7e40c.tar.gz android_packages_apps_DeskClock-1bd7a90878d1b580f68f32a4afa7df84b8a7e40c.tar.bz2 android_packages_apps_DeskClock-1bd7a90878d1b580f68f32a4afa7df84b8a7e40c.zip |
DeskClock: Add back flip and shake actions
Allow the alarm to be dismissed/snoozed by flipping or shaking
Picked from:
http://review.cyanogenmod.org/#/c/29894
http://review.cyanogenmod.org/#/c/80342
http://review.cyanogenmod.org/#/c/81204
http://review.cyanogenmod.org/#/c/94950
Authors/Contributors:
Artem Chep <artemchep@gmail.com>
Danny Baumann <dannybaumann@web.de>
Ronald Ramsay II <ronaldramsayii@gmail.com>
Danesh M <daneshm90@gmail.com>
Michael Bestas <mikeioannina@gmail.com>
Martin Brabham <mbrabham@cyngn.com>
Dan Pasanen <dan.pasanen@gmail.com> - Android 8.1 port
Change-Id: I222b6cd53a95db6f8662e7aef52aa6922d8a5d6a
-rw-r--r-- | res/values/cm_strings.xml | 15 | ||||
-rw-r--r-- | res/xml/settings.xml | 18 | ||||
-rw-r--r-- | src/com/android/deskclock/alarms/AlarmService.java | 167 | ||||
-rw-r--r-- | src/com/android/deskclock/data/AlarmModel.java | 8 | ||||
-rw-r--r-- | src/com/android/deskclock/data/DataModel.java | 8 | ||||
-rw-r--r-- | src/com/android/deskclock/data/SettingsDAO.java | 10 | ||||
-rw-r--r-- | src/com/android/deskclock/data/SettingsModel.java | 8 | ||||
-rw-r--r-- | src/com/android/deskclock/settings/SettingsActivity.java | 37 |
8 files changed, 269 insertions, 2 deletions
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml index 406988dfd..ebae31669 100644 --- a/res/values/cm_strings.xml +++ b/res/values/cm_strings.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2012-2016 The CyanogenMod Project + Copyright (C) 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. @@ -15,6 +16,20 @@ limitations under the License. --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Setting title for the flip action setting. --> + <string name="flip_action_title">Device flip action</string> + + <!-- Setting title for the shake action setting. --> + <string name="shake_action_title">Device shake action</string> + + <!-- Entries listed in the setting flip and shake. --> + <string-array name="action_setting_entries"> + <item>Snooze</item> + <item>Dismiss</item> + <item>Nothing</item> + </string-array> + <!-- Setting title for accessing the cLock widget settings --> <string name="menu_item_widget_settings">Widget settings</string> diff --git a/res/xml/settings.xml b/res/xml/settings.xml index 73c3359e6..e4e6f32b0 100644 --- a/res/xml/settings.xml +++ b/res/xml/settings.xml @@ -87,6 +87,22 @@ android:title="@string/volume_button_setting_title" /> <com.android.deskclock.settings.SimpleMenuPreference + android:defaultValue="0" + android:dialogTitle="@string/flip_action_title" + android:entries="@array/action_setting_entries" + android:entryValues="@array/volume_button_setting_values" + android:key="flip_action" + android:title="@string/flip_action_title" /> + + <com.android.deskclock.settings.SimpleMenuPreference + android:defaultValue="0" + android:dialogTitle="@string/shake_action_title" + android:entries="@array/action_setting_entries" + android:entryValues="@array/volume_button_setting_values" + android:key="shake_action" + android:title="@string/shake_action_title" /> + + <com.android.deskclock.settings.SimpleMenuPreference android:dialogTitle="@string/week_start_title" android:entries="@array/week_start_entries" android:entryValues="@array/week_start_values" @@ -115,4 +131,4 @@ android:title="@string/timer_vibrate_title" /> </PreferenceCategory> -</PreferenceScreen>
\ No newline at end of file +</PreferenceScreen> diff --git a/src/com/android/deskclock/alarms/AlarmService.java b/src/com/android/deskclock/alarms/AlarmService.java index b9a97db1b..67ae139be 100644 --- a/src/com/android/deskclock/alarms/AlarmService.java +++ b/src/com/android/deskclock/alarms/AlarmService.java @@ -21,6 +21,10 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.os.Binder; import android.os.IBinder; import android.telephony.PhoneStateListener; @@ -29,6 +33,7 @@ import android.telephony.TelephonyManager; import com.android.deskclock.AlarmAlertWakeLock; import com.android.deskclock.LogUtils; import com.android.deskclock.R; +import com.android.deskclock.data.DataModel; import com.android.deskclock.events.Events; import com.android.deskclock.provider.AlarmInstance; @@ -62,6 +67,14 @@ public class AlarmService extends Service { /** Private action used to stop an alarm with this service. */ public static final String STOP_ALARM_ACTION = "STOP_ALARM"; + // constants for no action/snooze/dismiss + private static final int ALARM_NO_ACTION = 0; + private static final int ALARM_SNOOZE = 1; + private static final int ALARM_DISMISS = 2; + + // default action for flip and shake + private static final String DEFAULT_ACTION = Integer.toString(ALARM_NO_ACTION); + /** Binder given to AlarmActivity. */ private final IBinder mBinder = new Binder(); @@ -103,6 +116,9 @@ public class AlarmService extends Service { private TelephonyManager mTelephonyManager; private AlarmInstance mCurrentAlarm = null; + private SensorManager mSensorManager; + private int mFlipAction; + private int mShakeAction; private void startAlarm(AlarmInstance instance) { LogUtils.v("AlarmService.start with instance: " + instance.mId); @@ -118,6 +134,7 @@ public class AlarmService extends Service { mTelephonyManager.listen(mPhoneStateListener.init(), PhoneStateListener.LISTEN_CALL_STATE); AlarmKlaxon.start(this, mCurrentAlarm); sendBroadcast(new Intent(ALARM_ALERT_ACTION)); + attachListeners(); } private void stopCurrentAlarm() { @@ -136,6 +153,7 @@ public class AlarmService extends Service { stopForeground(true /* removeNotification */); mCurrentAlarm = null; + detachListeners(); AlarmAlertWakeLock.releaseCpuLock(); } @@ -181,6 +199,11 @@ public class AlarmService extends Service { filter.addAction(ALARM_DISMISS_ACTION); registerReceiver(mActionsReceiver, filter); mIsRegistered = true; + + // set up for flip and shake actions + mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); + mFlipAction = DataModel.getDataModel().getFlipAction(); + mShakeAction = DataModel.getDataModel().getShakeAction(); } @Override @@ -264,4 +287,148 @@ public class AlarmService extends Service { } } } + + private final SensorEventListener mFlipListener = new SensorEventListener() { + private static final int FACE_UP_LOWER_LIMIT = -45; + private static final int FACE_UP_UPPER_LIMIT = 45; + private static final int FACE_DOWN_UPPER_LIMIT = 135; + private static final int FACE_DOWN_LOWER_LIMIT = -135; + private static final int TILT_UPPER_LIMIT = 45; + private static final int TILT_LOWER_LIMIT = -45; + private static final int SENSOR_SAMPLES = 3; + + private boolean mWasFaceUp; + private boolean[] mSamples = new boolean[SENSOR_SAMPLES]; + private int mSampleIndex; + + @Override + public void onAccuracyChanged(Sensor sensor, int acc) { + } + + @Override + public void onSensorChanged(SensorEvent event) { + // Add a sample overwriting the oldest one. Several samples + // are used + // to avoid the erroneous values the sensor sometimes + // returns. + float y = event.values[1]; + float z = event.values[2]; + + if (!mWasFaceUp) { + // Check if its face up enough. + mSamples[mSampleIndex] = y > FACE_UP_LOWER_LIMIT + && y < FACE_UP_UPPER_LIMIT + && z > TILT_LOWER_LIMIT && z < TILT_UPPER_LIMIT; + + // The device first needs to be face up. + boolean faceUp = true; + for (boolean sample : mSamples) { + faceUp = faceUp && sample; + } + if (faceUp) { + mWasFaceUp = true; + for (int i = 0; i < SENSOR_SAMPLES; i++) { + mSamples[i] = false; + } + } + } else { + // Check if its face down enough. Note that wanted + // values go from FACE_DOWN_UPPER_LIMIT to 180 + // and from -180 to FACE_DOWN_LOWER_LIMIT + mSamples[mSampleIndex] = (y > FACE_DOWN_UPPER_LIMIT || y < FACE_DOWN_LOWER_LIMIT) + && z > TILT_LOWER_LIMIT + && z < TILT_UPPER_LIMIT; + + boolean faceDown = true; + for (boolean sample : mSamples) { + faceDown = faceDown && sample; + } + if (faceDown) { + handleAction(mFlipAction); + } + } + + mSampleIndex = ((mSampleIndex + 1) % SENSOR_SAMPLES); + } + }; + + private final SensorEventListener mShakeListener = new SensorEventListener() { + private static final float SENSITIVITY = 16; + private static final int BUFFER = 5; + private float[] gravity = new float[3]; + private float average = 0; + private int fill = 0; + + @Override + public void onAccuracyChanged(Sensor sensor, int acc) { + } + + public void onSensorChanged(SensorEvent event) { + final float alpha = 0.8F; + + for (int i = 0; i < 3; i++) { + gravity[i] = alpha * gravity[i] + (1 - alpha) * event.values[i]; + } + + float x = event.values[0] - gravity[0]; + float y = event.values[1] - gravity[1]; + float z = event.values[2] - gravity[2]; + + if (fill <= BUFFER) { + average += Math.abs(x) + Math.abs(y) + Math.abs(z); + fill++; + } else { + if (average / BUFFER >= SENSITIVITY) { + handleAction(mShakeAction); + } + average = 0; + fill = 0; + } + } + }; + + private void attachListeners() { + if (mFlipAction != ALARM_NO_ACTION) { + mSensorManager.registerListener(mFlipListener, + mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), + SensorManager.SENSOR_DELAY_NORMAL, + 300 * 1000); //batch every 300 milliseconds + } + + if (mShakeAction != ALARM_NO_ACTION) { + mSensorManager.registerListener(mShakeListener, + mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), + SensorManager.SENSOR_DELAY_GAME, + 50 * 1000); //batch every 50 milliseconds + } + } + + private void detachListeners() { + if (mFlipAction != ALARM_NO_ACTION) { + mSensorManager.unregisterListener(mFlipListener); + } + if (mShakeAction != ALARM_NO_ACTION) { + mSensorManager.unregisterListener(mShakeListener); + } + } + + private void handleAction(int action) { + switch (action) { + case ALARM_SNOOZE: + // Setup Snooze Action + startService(AlarmStateManager.createStateChangeIntent(this, + AlarmStateManager.ALARM_SNOOZE_TAG, mCurrentAlarm, + AlarmInstance.SNOOZE_STATE)); + break; + case ALARM_DISMISS: + // Setup Dismiss Action + startService(AlarmStateManager.createStateChangeIntent(this, + AlarmStateManager.ALARM_DISMISS_TAG, mCurrentAlarm, + AlarmInstance.DISMISSED_STATE)); + break; + case ALARM_NO_ACTION: + default: + break; + } + } } diff --git a/src/com/android/deskclock/data/AlarmModel.java b/src/com/android/deskclock/data/AlarmModel.java index da50fe550..cc1a42eb1 100644 --- a/src/com/android/deskclock/data/AlarmModel.java +++ b/src/com/android/deskclock/data/AlarmModel.java @@ -78,6 +78,14 @@ final class AlarmModel { return mSettingsModel.getSnoozeLength(); } + int getFlipAction() { + return mSettingsModel.getFlipAction(); + } + + int getShakeAction() { + return mSettingsModel.getShakeAction(); + } + /** * This receiver is notified when system settings change. Cached information built on * those system settings must be cleared. diff --git a/src/com/android/deskclock/data/DataModel.java b/src/com/android/deskclock/data/DataModel.java index 2b16ae84f..1be8468a4 100644 --- a/src/com/android/deskclock/data/DataModel.java +++ b/src/com/android/deskclock/data/DataModel.java @@ -735,6 +735,14 @@ public final class DataModel { return mAlarmModel.getSnoozeLength(); } + public int getFlipAction() { + return mAlarmModel.getFlipAction(); + } + + public int getShakeAction() { + return mAlarmModel.getShakeAction(); + } + // // Stopwatch // diff --git a/src/com/android/deskclock/data/SettingsDAO.java b/src/com/android/deskclock/data/SettingsDAO.java index 7e9408f3a..3fe7c6b79 100644 --- a/src/com/android/deskclock/data/SettingsDAO.java +++ b/src/com/android/deskclock/data/SettingsDAO.java @@ -349,6 +349,16 @@ final class SettingsDAO { return new TimeZones(tzIds, tzNames); } + static int getFlipAction(SharedPreferences prefs) { + final String string = prefs.getString(SettingsActivity.KEY_FLIP_ACTION, "0"); + return Integer.parseInt(string); + } + + static int getShakeAction(SharedPreferences prefs) { + final String string = prefs.getString(SettingsActivity.KEY_SHAKE_ACTION, "0"); + return Integer.parseInt(string); + } + private static ClockStyle getClockStyle(Context context, SharedPreferences prefs, String key) { final String defaultStyle = context.getString(R.string.default_clock_style); final String clockStyle = prefs.getString(key, defaultStyle); diff --git a/src/com/android/deskclock/data/SettingsModel.java b/src/com/android/deskclock/data/SettingsModel.java index 103c21046..e41a89338 100644 --- a/src/com/android/deskclock/data/SettingsModel.java +++ b/src/com/android/deskclock/data/SettingsModel.java @@ -133,6 +133,14 @@ final class SettingsModel { return SettingsDAO.getSnoozeLength(mPrefs); } + int getFlipAction() { + return SettingsDAO.getFlipAction(mPrefs); + } + + int getShakeAction() { + return SettingsDAO.getShakeAction(mPrefs); + } + Uri getDefaultAlarmRingtoneUri() { return SettingsDAO.getDefaultAlarmRingtoneUri(mPrefs); } diff --git a/src/com/android/deskclock/settings/SettingsActivity.java b/src/com/android/deskclock/settings/SettingsActivity.java index 59a7b7399..d8d739516 100644 --- a/src/com/android/deskclock/settings/SettingsActivity.java +++ b/src/com/android/deskclock/settings/SettingsActivity.java @@ -18,6 +18,8 @@ package com.android.deskclock.settings; import android.content.Context; import android.content.Intent; +import android.hardware.Sensor; +import android.hardware.SensorManager; import android.os.Bundle; import android.os.Vibrator; import android.provider.Settings; @@ -43,6 +45,8 @@ import com.android.deskclock.data.TimeZones; import com.android.deskclock.data.Weekdays; import com.android.deskclock.ringtone.RingtonePickerActivity; +import java.util.List; + /** * Settings for the Alarm Clock. */ @@ -61,6 +65,8 @@ public final class SettingsActivity extends BaseActivity { public static final String KEY_DATE_TIME = "date_time"; public static final String KEY_VOLUME_BUTTONS = "volume_button_setting"; public static final String KEY_WEEK_START = "week_start"; + public static final String KEY_FLIP_ACTION = "flip_action"; + public static final String KEY_SHAKE_ACTION = "shake_action"; public static final String DEFAULT_VOLUME_BEHAVIOR = "0"; public static final String VOLUME_BEHAVIOR_SNOOZE = "1"; @@ -171,6 +177,8 @@ public final class SettingsActivity extends BaseActivity { case KEY_CLOCK_STYLE: case KEY_WEEK_START: case KEY_VOLUME_BUTTONS: + case KEY_FLIP_ACTION: + case KEY_SHAKE_ACTION: final SimpleMenuPreference simpleMenuPreference = (SimpleMenuPreference) pref; final int i = simpleMenuPreference.findIndexOfValue((String) newValue); pref.setSummary(simpleMenuPreference.getEntries()[i]); @@ -308,6 +316,33 @@ public final class SettingsActivity extends BaseActivity { final Preference timerRingtonePref = findPreference(KEY_TIMER_RINGTONE); timerRingtonePref.setOnPreferenceClickListener(this); timerRingtonePref.setSummary(DataModel.getDataModel().getTimerRingtoneTitle()); + + SensorManager sensorManager = (SensorManager) + getActivity().getSystemService(Context.SENSOR_SERVICE); + + final SimpleMenuPreference flipActionPref = + (SimpleMenuPreference) findPreference(KEY_FLIP_ACTION); + if (flipActionPref != null) { + List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION); + if (sensorList.size() < 1) { // This will be true if no orientation sensor + flipActionPref.setValue("0"); // Turn it off + } else { + flipActionPref.setSummary(flipActionPref.getEntry()); + flipActionPref.setOnPreferenceChangeListener(this); + } + } + + final SimpleMenuPreference shakeActionPref = + (SimpleMenuPreference) findPreference(KEY_SHAKE_ACTION); + if (shakeActionPref != null) { + List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); + if (sensorList.size() < 1) { // This will be true if no accelerometer sensor + shakeActionPref.setValue("0"); // Turn it off + } else { + shakeActionPref.setSummary(shakeActionPref.getEntry()); + shakeActionPref.setOnPreferenceChangeListener(this); + } + } } private void refreshListPreference(ListPreference preference) { @@ -325,4 +360,4 @@ public final class SettingsActivity extends BaseActivity { } } } -}
\ No newline at end of file +} |