blob: 3afdc3db427aceae897df66acf647a74f014ba94 [file] [log] [blame]
John Spurlockbf370992014-06-17 13:58:31 -04001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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
15 */
16
17package com.android.systemui.doze;
18
John Spurlockcb566aa2014-08-03 22:58:28 -040019import android.app.AlarmManager;
20import android.app.PendingIntent;
John Spurlock870f1532014-09-25 20:34:31 -040021import android.app.UiModeManager;
John Spurlockbf370992014-06-17 13:58:31 -040022import android.content.BroadcastReceiver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.IntentFilter;
John Spurlock870f1532014-09-25 20:34:31 -040026import android.content.res.Configuration;
John Spurlockbf370992014-06-17 13:58:31 -040027import android.hardware.Sensor;
28import android.hardware.SensorManager;
29import android.hardware.TriggerEvent;
30import android.hardware.TriggerEventListener;
John Spurlock559d9592014-08-09 12:04:36 -040031import android.media.AudioAttributes;
John Spurlockbf370992014-06-17 13:58:31 -040032import android.os.PowerManager;
33import android.os.Vibrator;
John Spurlockbf370992014-06-17 13:58:31 -040034import android.service.dreams.DreamService;
35import android.util.Log;
John Spurlocked69bd62014-07-23 11:09:02 -040036import android.view.Display;
John Spurlockbf370992014-06-17 13:58:31 -040037
38import com.android.systemui.SystemUIApplication;
John Spurlockd06aa572014-09-10 10:40:49 -040039import com.android.systemui.statusbar.phone.DozeParameters;
John Spurlock190d0262014-09-14 15:39:13 -040040import com.android.systemui.statusbar.phone.DozeParameters.PulseSchedule;
John Spurlockbf370992014-06-17 13:58:31 -040041
John Spurlock66127272014-06-28 11:27:17 -040042import java.io.FileDescriptor;
43import java.io.PrintWriter;
John Spurlockcb566aa2014-08-03 22:58:28 -040044import java.util.Date;
John Spurlock66127272014-06-28 11:27:17 -040045
John Spurlockbf370992014-06-17 13:58:31 -040046public class DozeService extends DreamService {
John Spurlocked69bd62014-07-23 11:09:02 -040047 private static final String TAG = "DozeService";
48 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
John Spurlockbf370992014-06-17 13:58:31 -040049
John Spurlockcb566aa2014-08-03 22:58:28 -040050 private static final String ACTION_BASE = "com.android.systemui.doze";
51 private static final String PULSE_ACTION = ACTION_BASE + ".pulse";
52 private static final String NOTIFICATION_PULSE_ACTION = ACTION_BASE + ".notification_pulse";
John Spurlock813552c2014-09-19 08:30:21 -040053 private static final String EXTRA_INSTANCE = "instance";
John Spurlockbf370992014-06-17 13:58:31 -040054
John Spurlocked69bd62014-07-23 11:09:02 -040055 private final String mTag = String.format(TAG + ".%08x", hashCode());
John Spurlockbf370992014-06-17 13:58:31 -040056 private final Context mContext = this;
John Spurlockd06aa572014-09-10 10:40:49 -040057 private final DozeParameters mDozeParameters = new DozeParameters(mContext);
John Spurlockbf370992014-06-17 13:58:31 -040058
Jeff Brown4d69e222014-09-18 15:27:50 -070059 private DozeHost mHost;
John Spurlockbf370992014-06-17 13:58:31 -040060 private SensorManager mSensors;
John Spurlock559d9592014-08-09 12:04:36 -040061 private TriggerSensor mSigMotionSensor;
62 private TriggerSensor mPickupSensor;
John Spurlockbf370992014-06-17 13:58:31 -040063 private PowerManager mPowerManager;
64 private PowerManager.WakeLock mWakeLock;
John Spurlockcb566aa2014-08-03 22:58:28 -040065 private AlarmManager mAlarmManager;
John Spurlock870f1532014-09-25 20:34:31 -040066 private UiModeManager mUiModeManager;
John Spurlockbf370992014-06-17 13:58:31 -040067 private boolean mDreaming;
Jeff Brown4d69e222014-09-18 15:27:50 -070068 private boolean mPulsing;
John Spurlockcb566aa2014-08-03 22:58:28 -040069 private boolean mBroadcastReceiverRegistered;
John Spurlocked69bd62014-07-23 11:09:02 -040070 private boolean mDisplayStateSupported;
John Spurlockcb566aa2014-08-03 22:58:28 -040071 private boolean mNotificationLightOn;
John Spurlockd96179e2014-08-21 16:43:45 -040072 private boolean mPowerSaveActive;
John Spurlock870f1532014-09-25 20:34:31 -040073 private boolean mCarMode;
John Spurlockd06aa572014-09-10 10:40:49 -040074 private long mNotificationPulseTime;
John Spurlock190d0262014-09-14 15:39:13 -040075 private int mScheduleResetsRemaining;
John Spurlockbf370992014-06-17 13:58:31 -040076
77 public DozeService() {
78 if (DEBUG) Log.d(mTag, "new DozeService()");
79 setDebug(DEBUG);
80 }
81
82 @Override
John Spurlock66127272014-06-28 11:27:17 -040083 protected void dumpOnHandler(FileDescriptor fd, PrintWriter pw, String[] args) {
84 super.dumpOnHandler(fd, pw, args);
85 pw.print(" mDreaming: "); pw.println(mDreaming);
Jeff Brown4d69e222014-09-18 15:27:50 -070086 pw.print(" mPulsing: "); pw.println(mPulsing);
87 pw.print(" mWakeLock: held="); pw.println(mWakeLock.isHeld());
John Spurlockc6eed842014-08-25 12:19:41 -040088 pw.print(" mHost: "); pw.println(mHost);
John Spurlockcb566aa2014-08-03 22:58:28 -040089 pw.print(" mBroadcastReceiverRegistered: "); pw.println(mBroadcastReceiverRegistered);
John Spurlock66127272014-06-28 11:27:17 -040090 pw.print(" mSigMotionSensor: "); pw.println(mSigMotionSensor);
John Spurlock559d9592014-08-09 12:04:36 -040091 pw.print(" mPickupSensor:"); pw.println(mPickupSensor);
John Spurlocked69bd62014-07-23 11:09:02 -040092 pw.print(" mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
John Spurlockcb566aa2014-08-03 22:58:28 -040093 pw.print(" mNotificationLightOn: "); pw.println(mNotificationLightOn);
John Spurlockd96179e2014-08-21 16:43:45 -040094 pw.print(" mPowerSaveActive: "); pw.println(mPowerSaveActive);
John Spurlock870f1532014-09-25 20:34:31 -040095 pw.print(" mCarMode: "); pw.println(mCarMode);
John Spurlockd06aa572014-09-10 10:40:49 -040096 pw.print(" mNotificationPulseTime: "); pw.println(mNotificationPulseTime);
John Spurlock190d0262014-09-14 15:39:13 -040097 pw.print(" mScheduleResetsRemaining: "); pw.println(mScheduleResetsRemaining);
John Spurlockd06aa572014-09-10 10:40:49 -040098 mDozeParameters.dump(pw);
John Spurlock66127272014-06-28 11:27:17 -040099 }
100
101 @Override
John Spurlockbf370992014-06-17 13:58:31 -0400102 public void onCreate() {
103 if (DEBUG) Log.d(mTag, "onCreate");
104 super.onCreate();
105
106 if (getApplication() instanceof SystemUIApplication) {
107 final SystemUIApplication app = (SystemUIApplication) getApplication();
Jeff Brown4d69e222014-09-18 15:27:50 -0700108 mHost = app.getComponent(DozeHost.class);
John Spurlockbf370992014-06-17 13:58:31 -0400109 }
John Spurlockc6eed842014-08-25 12:19:41 -0400110 if (mHost == null) Log.w(TAG, "No doze service host found.");
John Spurlockbf370992014-06-17 13:58:31 -0400111
112 setWindowless(true);
113
114 mSensors = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
John Spurlock190d0262014-09-14 15:39:13 -0400115 mSigMotionSensor = new TriggerSensor(Sensor.TYPE_SIGNIFICANT_MOTION,
116 mDozeParameters.getPulseOnSigMotion(), mDozeParameters.getVibrateOnSigMotion());
117 mPickupSensor = new TriggerSensor(Sensor.TYPE_PICK_UP_GESTURE,
118 mDozeParameters.getPulseOnPickup(), mDozeParameters.getVibrateOnPickup());
John Spurlockbf370992014-06-17 13:58:31 -0400119 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
120 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);
Jeff Brown4d69e222014-09-18 15:27:50 -0700121 mWakeLock.setReferenceCounted(true);
John Spurlockcb566aa2014-08-03 22:58:28 -0400122 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
John Spurlock190d0262014-09-14 15:39:13 -0400123 mDisplayStateSupported = mDozeParameters.getDisplayStateSupported();
John Spurlock870f1532014-09-25 20:34:31 -0400124 mUiModeManager = (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE);
Jeff Brown4d69e222014-09-18 15:27:50 -0700125 turnDisplayOff();
John Spurlockbf370992014-06-17 13:58:31 -0400126 }
127
128 @Override
129 public void onAttachedToWindow() {
130 if (DEBUG) Log.d(mTag, "onAttachedToWindow");
131 super.onAttachedToWindow();
132 }
133
134 @Override
135 public void onDreamingStarted() {
136 super.onDreamingStarted();
Jeff Brown4d69e222014-09-18 15:27:50 -0700137
138 if (mHost == null) {
139 finish();
140 return;
141 }
142
143 mPowerSaveActive = mHost.isPowerSaveActive();
John Spurlock870f1532014-09-25 20:34:31 -0400144 mCarMode = mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR;
John Spurlockd96179e2014-08-21 16:43:45 -0400145 if (DEBUG) Log.d(mTag, "onDreamingStarted canDoze=" + canDoze() + " mPowerSaveActive="
John Spurlock870f1532014-09-25 20:34:31 -0400146 + mPowerSaveActive + " mCarMode=" + mCarMode);
John Spurlockd96179e2014-08-21 16:43:45 -0400147 if (mPowerSaveActive) {
148 finishToSavePower();
149 return;
150 }
John Spurlock870f1532014-09-25 20:34:31 -0400151 if (mCarMode) {
152 finishForCarMode();
153 return;
154 }
Jeff Brown4d69e222014-09-18 15:27:50 -0700155
John Spurlockbf370992014-06-17 13:58:31 -0400156 mDreaming = true;
John Spurlockcb566aa2014-08-03 22:58:28 -0400157 listenForPulseSignals(true);
John Spurlock190d0262014-09-14 15:39:13 -0400158 rescheduleNotificationPulse(false /*predicate*/); // cancel any pending pulse alarms
John Spurlockbf370992014-06-17 13:58:31 -0400159
Jeff Brown4d69e222014-09-18 15:27:50 -0700160 // Ask the host to get things ready to start dozing.
161 // Once ready, we call startDozing() at which point the CPU may suspend
162 // and we will need to acquire a wakelock to do work.
163 mHost.startDozing(new Runnable() {
164 @Override
165 public void run() {
166 if (mDreaming) {
167 startDozing();
John Spurlockbf370992014-06-17 13:58:31 -0400168
Jeff Brown4d69e222014-09-18 15:27:50 -0700169 // From this point until onDreamingStopped we will need to hold a
170 // wakelock whenever we are doing work. Note that we never call
171 // stopDozing because can we just keep dozing until the bitter end.
172 }
173 }
174 });
John Spurlocked69bd62014-07-23 11:09:02 -0400175 }
176
John Spurlockbf370992014-06-17 13:58:31 -0400177 @Override
178 public void onDreamingStopped() {
179 if (DEBUG) Log.d(mTag, "onDreamingStopped isDozing=" + isDozing());
180 super.onDreamingStopped();
181
Jeff Brown4d69e222014-09-18 15:27:50 -0700182 if (mHost == null) {
183 return;
184 }
185
John Spurlockbf370992014-06-17 13:58:31 -0400186 mDreaming = false;
John Spurlockcb566aa2014-08-03 22:58:28 -0400187 listenForPulseSignals(false);
John Spurlockbf370992014-06-17 13:58:31 -0400188
Jeff Brown4d69e222014-09-18 15:27:50 -0700189 // Tell the host that it's over.
190 mHost.stopDozing();
John Spurlockbf370992014-06-17 13:58:31 -0400191 }
192
John Spurlock190d0262014-09-14 15:39:13 -0400193 private void requestPulse() {
Jeff Brown4d69e222014-09-18 15:27:50 -0700194 if (mHost != null && mDreaming && !mPulsing) {
195 // Let the host know we want to pulse. Wait for it to be ready, then
196 // turn the screen on. When finished, turn the screen off again.
197 // Here we need a wakelock to stay awake until the pulse is finished.
198 mWakeLock.acquire();
199 mPulsing = true;
200 mHost.pulseWhileDozing(new DozeHost.PulseCallback() {
201 @Override
202 public void onPulseStarted() {
203 if (mPulsing && mDreaming) {
204 turnDisplayOn();
205 }
206 }
207
208 @Override
209 public void onPulseFinished() {
210 if (mPulsing && mDreaming) {
211 mPulsing = false;
212 turnDisplayOff();
Jeff Brown4d69e222014-09-18 15:27:50 -0700213 }
Jeff Browna2739242014-09-22 22:30:22 -0700214 mWakeLock.release(); // needs to be unconditional to balance acquire
Jeff Brown4d69e222014-09-18 15:27:50 -0700215 }
216 });
John Spurlockbf370992014-06-17 13:58:31 -0400217 }
218 }
219
Jeff Brown4d69e222014-09-18 15:27:50 -0700220 private void turnDisplayOff() {
221 if (DEBUG) Log.d(TAG, "Display off");
222 setDozeScreenState(Display.STATE_OFF);
223 }
224
225 private void turnDisplayOn() {
226 if (DEBUG) Log.d(TAG, "Display on");
227 setDozeScreenState(mDisplayStateSupported ? Display.STATE_DOZE : Display.STATE_ON);
John Spurlockbf370992014-06-17 13:58:31 -0400228 }
229
John Spurlockd96179e2014-08-21 16:43:45 -0400230 private void finishToSavePower() {
231 Log.w(mTag, "Exiting ambient mode due to low power battery saver");
232 finish();
233 }
234
John Spurlock870f1532014-09-25 20:34:31 -0400235 private void finishForCarMode() {
236 Log.w(mTag, "Exiting ambient mode, not allowed in car mode");
237 finish();
238 }
239
John Spurlockcb566aa2014-08-03 22:58:28 -0400240 private void listenForPulseSignals(boolean listen) {
241 if (DEBUG) Log.d(mTag, "listenForPulseSignals: " + listen);
John Spurlock559d9592014-08-09 12:04:36 -0400242 mSigMotionSensor.setListening(listen);
243 mPickupSensor.setListening(listen);
John Spurlockcb566aa2014-08-03 22:58:28 -0400244 listenForBroadcasts(listen);
John Spurlock66127272014-06-28 11:27:17 -0400245 listenForNotifications(listen);
246 }
247
John Spurlockcb566aa2014-08-03 22:58:28 -0400248 private void listenForBroadcasts(boolean listen) {
John Spurlockbf370992014-06-17 13:58:31 -0400249 if (listen) {
John Spurlockcb566aa2014-08-03 22:58:28 -0400250 final IntentFilter filter = new IntentFilter(PULSE_ACTION);
251 filter.addAction(NOTIFICATION_PULSE_ACTION);
John Spurlock870f1532014-09-25 20:34:31 -0400252 filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
John Spurlockcb566aa2014-08-03 22:58:28 -0400253 mContext.registerReceiver(mBroadcastReceiver, filter);
254 mBroadcastReceiverRegistered = true;
John Spurlockbf370992014-06-17 13:58:31 -0400255 } else {
John Spurlockcb566aa2014-08-03 22:58:28 -0400256 if (mBroadcastReceiverRegistered) {
257 mContext.unregisterReceiver(mBroadcastReceiver);
John Spurlockbf370992014-06-17 13:58:31 -0400258 }
John Spurlockcb566aa2014-08-03 22:58:28 -0400259 mBroadcastReceiverRegistered = false;
John Spurlockbf370992014-06-17 13:58:31 -0400260 }
261 }
262
John Spurlock66127272014-06-28 11:27:17 -0400263 private void listenForNotifications(boolean listen) {
John Spurlockbf370992014-06-17 13:58:31 -0400264 if (listen) {
John Spurlock190d0262014-09-14 15:39:13 -0400265 resetNotificationResets();
John Spurlock66127272014-06-28 11:27:17 -0400266 mHost.addCallback(mHostCallback);
John Spurlockbf370992014-06-17 13:58:31 -0400267 } else {
John Spurlock66127272014-06-28 11:27:17 -0400268 mHost.removeCallback(mHostCallback);
John Spurlockbf370992014-06-17 13:58:31 -0400269 }
270 }
271
John Spurlock190d0262014-09-14 15:39:13 -0400272 private void resetNotificationResets() {
273 if (DEBUG) Log.d(TAG, "resetNotificationResets");
274 mScheduleResetsRemaining = mDozeParameters.getPulseScheduleResets();
275 }
276
277 private void updateNotificationPulse() {
278 if (DEBUG) Log.d(TAG, "updateNotificationPulse");
279 if (!mDozeParameters.getPulseOnNotifications()) return;
280 if (mScheduleResetsRemaining <= 0) {
281 if (DEBUG) Log.d(TAG, "No more schedule resets remaining");
282 return;
John Spurlockcb566aa2014-08-03 22:58:28 -0400283 }
John Spurlock190d0262014-09-14 15:39:13 -0400284 final long now = System.currentTimeMillis();
285 if ((now - mNotificationPulseTime) < mDozeParameters.getPulseDuration()) {
286 if (DEBUG) Log.d(TAG, "Recently updated, not resetting schedule");
287 return;
288 }
289 mScheduleResetsRemaining--;
290 if (DEBUG) Log.d(TAG, "mScheduleResetsRemaining = " + mScheduleResetsRemaining);
291 mNotificationPulseTime = now;
292 rescheduleNotificationPulse(true /*predicate*/);
293 }
294
John Spurlock813552c2014-09-19 08:30:21 -0400295 private PendingIntent notificationPulseIntent(long instance) {
296 return PendingIntent.getBroadcast(mContext, 0,
Jeff Brown4d69e222014-09-18 15:27:50 -0700297 new Intent(NOTIFICATION_PULSE_ACTION)
298 .setPackage(getPackageName())
299 .putExtra(EXTRA_INSTANCE, instance)
300 .setFlags(Intent.FLAG_RECEIVER_FOREGROUND),
John Spurlock813552c2014-09-19 08:30:21 -0400301 PendingIntent.FLAG_UPDATE_CURRENT);
302 }
303
John Spurlock190d0262014-09-14 15:39:13 -0400304 private void rescheduleNotificationPulse(boolean predicate) {
305 if (DEBUG) Log.d(TAG, "rescheduleNotificationPulse predicate=" + predicate);
John Spurlock813552c2014-09-19 08:30:21 -0400306 final PendingIntent notificationPulseIntent = notificationPulseIntent(0);
307 mAlarmManager.cancel(notificationPulseIntent);
John Spurlock190d0262014-09-14 15:39:13 -0400308 if (!predicate) {
309 if (DEBUG) Log.d(TAG, " don't reschedule: predicate is false");
310 return;
311 }
312 final PulseSchedule schedule = mDozeParameters.getPulseSchedule();
313 if (schedule == null) {
314 if (DEBUG) Log.d(TAG, " don't reschedule: schedule is null");
315 return;
316 }
317 final long now = System.currentTimeMillis();
318 final long time = schedule.getNextTime(now, mNotificationPulseTime);
319 if (time <= 0) {
320 if (DEBUG) Log.d(TAG, " don't reschedule: time is " + time);
321 return;
322 }
323 final long delta = time - now;
324 if (delta <= 0) {
325 if (DEBUG) Log.d(TAG, " don't reschedule: delta is " + delta);
326 return;
327 }
John Spurlock813552c2014-09-19 08:30:21 -0400328 final long instance = time - mNotificationPulseTime;
329 if (DEBUG) Log.d(TAG, "Scheduling pulse " + instance + " in " + delta + "ms for "
330 + new Date(time));
331 mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, notificationPulseIntent(instance));
John Spurlockcb566aa2014-08-03 22:58:28 -0400332 }
333
John Spurlockbf370992014-06-17 13:58:31 -0400334 private static String triggerEventToString(TriggerEvent event) {
335 if (event == null) return null;
336 final StringBuilder sb = new StringBuilder("TriggerEvent[")
337 .append(event.timestamp).append(',')
338 .append(event.sensor.getName());
339 if (event.values != null) {
340 for (int i = 0; i < event.values.length; i++) {
341 sb.append(',').append(event.values[i]);
342 }
343 }
344 return sb.append(']').toString();
345 }
346
John Spurlockcb566aa2014-08-03 22:58:28 -0400347 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
John Spurlockbf370992014-06-17 13:58:31 -0400348 @Override
349 public void onReceive(Context context, Intent intent) {
John Spurlockcb566aa2014-08-03 22:58:28 -0400350 if (PULSE_ACTION.equals(intent.getAction())) {
351 if (DEBUG) Log.d(mTag, "Received pulse intent");
John Spurlock190d0262014-09-14 15:39:13 -0400352 requestPulse();
John Spurlockcb566aa2014-08-03 22:58:28 -0400353 }
354 if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) {
John Spurlock813552c2014-09-19 08:30:21 -0400355 final long instance = intent.getLongExtra(EXTRA_INSTANCE, -1);
356 if (DEBUG) Log.d(mTag, "Received notification pulse intent instance=" + instance);
357 DozeLog.traceNotificationPulse(instance);
John Spurlock190d0262014-09-14 15:39:13 -0400358 requestPulse();
359 rescheduleNotificationPulse(mNotificationLightOn);
John Spurlockcb566aa2014-08-03 22:58:28 -0400360 }
John Spurlock870f1532014-09-25 20:34:31 -0400361 if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
362 mCarMode = true;
363 if (mCarMode && mDreaming) {
364 finishForCarMode();
365 }
366 }
John Spurlockbf370992014-06-17 13:58:31 -0400367 }
368 };
369
Jeff Brown4d69e222014-09-18 15:27:50 -0700370 private final DozeHost.Callback mHostCallback = new DozeHost.Callback() {
John Spurlockbf370992014-06-17 13:58:31 -0400371 @Override
372 public void onNewNotifications() {
373 if (DEBUG) Log.d(mTag, "onNewNotifications");
John Spurlockcad57682014-07-26 17:09:56 -0400374 // noop for now
375 }
John Spurlockcb566aa2014-08-03 22:58:28 -0400376
John Spurlockcad57682014-07-26 17:09:56 -0400377 @Override
378 public void onBuzzBeepBlinked() {
379 if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked");
John Spurlock190d0262014-09-14 15:39:13 -0400380 updateNotificationPulse();
John Spurlockcb566aa2014-08-03 22:58:28 -0400381 }
382
383 @Override
384 public void onNotificationLight(boolean on) {
385 if (DEBUG) Log.d(mTag, "onNotificationLight on=" + on);
386 if (mNotificationLightOn == on) return;
387 mNotificationLightOn = on;
John Spurlockd06aa572014-09-10 10:40:49 -0400388 if (mNotificationLightOn) {
John Spurlock190d0262014-09-14 15:39:13 -0400389 updateNotificationPulse();
John Spurlockd06aa572014-09-10 10:40:49 -0400390 }
John Spurlockbf370992014-06-17 13:58:31 -0400391 }
John Spurlockd96179e2014-08-21 16:43:45 -0400392
393 @Override
394 public void onPowerSaveChanged(boolean active) {
395 mPowerSaveActive = active;
396 if (mPowerSaveActive && mDreaming) {
397 finishToSavePower();
398 }
399 }
John Spurlockbf370992014-06-17 13:58:31 -0400400 };
401
John Spurlock559d9592014-08-09 12:04:36 -0400402 private class TriggerSensor extends TriggerEventListener {
403 private final Sensor mSensor;
404 private final boolean mConfigured;
John Spurlock190d0262014-09-14 15:39:13 -0400405 private final boolean mDebugVibrate;
John Spurlock559d9592014-08-09 12:04:36 -0400406
407 private boolean mEnabled;
408
John Spurlock190d0262014-09-14 15:39:13 -0400409 public TriggerSensor(int type, boolean configured, boolean debugVibrate) {
John Spurlock559d9592014-08-09 12:04:36 -0400410 mSensor = mSensors.getDefaultSensor(type);
John Spurlock190d0262014-09-14 15:39:13 -0400411 mConfigured = configured;
412 mDebugVibrate = debugVibrate;
John Spurlock559d9592014-08-09 12:04:36 -0400413 }
414
415 public void setListening(boolean listen) {
416 if (!mConfigured || mSensor == null) return;
417 if (listen) {
418 mEnabled = mSensors.requestTriggerSensor(this, mSensor);
419 } else if (mEnabled) {
420 mSensors.cancelTriggerSensor(this, mSensor);
421 mEnabled = false;
422 }
423 }
424
425 @Override
426 public String toString() {
427 return new StringBuilder("{mEnabled=").append(mEnabled).append(", mConfigured=")
John Spurlock190d0262014-09-14 15:39:13 -0400428 .append(mConfigured).append(", mDebugVibrate=").append(mDebugVibrate)
429 .append(", mSensor=").append(mSensor).append("}").toString();
John Spurlock559d9592014-08-09 12:04:36 -0400430 }
431
432 @Override
433 public void onTrigger(TriggerEvent event) {
Jeff Brown4d69e222014-09-18 15:27:50 -0700434 mWakeLock.acquire();
435 try {
436 if (DEBUG) Log.d(mTag, "onTrigger: " + triggerEventToString(event));
437 if (mDebugVibrate) {
438 final Vibrator v = (Vibrator) mContext.getSystemService(
439 Context.VIBRATOR_SERVICE);
440 if (v != null) {
441 v.vibrate(1000, new AudioAttributes.Builder()
442 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
443 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build());
444 }
John Spurlock559d9592014-08-09 12:04:36 -0400445 }
John Spurlock50a8ea62014-09-16 09:12:03 -0400446
Jeff Brown4d69e222014-09-18 15:27:50 -0700447 requestPulse();
448 setListening(true); // reregister, this sensor only fires once
449
450 // reset the notification pulse schedule, but only if we think we were not triggered
451 // by a notification-related vibration
452 final long timeSinceNotification = System.currentTimeMillis() - mNotificationPulseTime;
453 final boolean withinVibrationThreshold =
454 timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
455 if (withinVibrationThreshold) {
456 if (DEBUG) Log.d(mTag, "Not resetting schedule, recent notification");
457 } else {
458 resetNotificationResets();
459 }
460 if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
461 DozeLog.tracePickupPulse(withinVibrationThreshold);
462 }
463 } finally {
464 mWakeLock.release();
John Spurlock813552c2014-09-19 08:30:21 -0400465 }
John Spurlock559d9592014-08-09 12:04:36 -0400466 }
467 }
John Spurlockbf370992014-06-17 13:58:31 -0400468}