summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android/systemui/doze
diff options
context:
space:
mode:
authorJohn Spurlock <jspurlock@google.com>2014-06-17 13:58:31 -0400
committerJohn Spurlock <jspurlock@google.com>2014-06-25 13:33:09 -0400
commitbf370992508c55d1f2493923bdc1834a0710e4ba (patch)
tree4be1a3567ebe163297be36da5ac6d51539964922 /packages/SystemUI/src/com/android/systemui/doze
parent828d11df52680ad75e045f5e4251311605d37af2 (diff)
downloadframeworks_base-bf370992508c55d1f2493923bdc1834a0710e4ba.zip
frameworks_base-bf370992508c55d1f2493923bdc1834a0710e4ba.tar.gz
frameworks_base-bf370992508c55d1f2493923bdc1834a0710e4ba.tar.bz2
Create a basic doze dream in SystemUI.
The doze dream is not configured by default. When configured, the doze dream does not show anything by default. It teases a dark version of the keyguard (showing only the time and notifications) when a notification arrives or significant motion is detected. Bug:15863249 Change-Id: Icfceb054d35d6fd4d9178eda7480e2464873ca4b
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/doze')
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeService.java238
1 files changed, 238 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
new file mode 100644
index 0000000..cc0d4a7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -0,0 +1,238 @@
+/*
+ * 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
+ */
+
+package com.android.systemui.doze;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
+import android.os.PowerManager;
+import android.os.Vibrator;
+import android.service.dreams.DozeHardware;
+import android.service.dreams.DreamService;
+import android.util.Log;
+
+import com.android.systemui.SystemUIApplication;
+
+public class DozeService extends DreamService {
+ private static final boolean DEBUG = false;
+
+ private static final String TEASE_ACTION = "com.android.systemui.doze.tease";
+
+ private final String mTag = String.format("DozeService.%08x", hashCode());
+ private final Context mContext = this;
+
+ private Host mHost;
+ private DozeHardware mDozeHardware;
+ private SensorManager mSensors;
+ private Sensor mSigMotionSensor;
+ private PowerManager mPowerManager;
+ private PowerManager.WakeLock mWakeLock;
+ private boolean mDreaming;
+ private boolean mTeaseReceiverRegistered;
+
+ public DozeService() {
+ if (DEBUG) Log.d(mTag, "new DozeService()");
+ setDebug(DEBUG);
+ }
+
+ @Override
+ public void onCreate() {
+ if (DEBUG) Log.d(mTag, "onCreate");
+ super.onCreate();
+
+ if (getApplication() instanceof SystemUIApplication) {
+ final SystemUIApplication app = (SystemUIApplication) getApplication();
+ mHost = app.getComponent(Host.class);
+ }
+
+ setWindowless(true);
+
+ mSensors = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
+ mSigMotionSensor = mSensors.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ if (DEBUG) Log.d(mTag, "onAttachedToWindow");
+ super.onAttachedToWindow();
+ }
+
+ @Override
+ public void onDreamingStarted() {
+ super.onDreamingStarted();
+ mDozeHardware = getDozeHardware();
+ if (DEBUG) Log.d(mTag, "onDreamingStarted canDoze=" + canDoze()
+ + " dozeHardware=" + mDozeHardware);
+ mDreaming = true;
+ listenForTeaseSignals(true);
+ requestDoze();
+ }
+
+ public void stayAwake(long millis) {
+ if (mDreaming && millis > 0) {
+ mWakeLock.acquire(millis);
+ }
+ }
+
+ public void startDozing() {
+ if (DEBUG) Log.d(mTag, "startDozing mDreaming=" + mDreaming);
+ if (!mDreaming) {
+ Log.w(mTag, "Not dozing, no longer dreaming");
+ return;
+ }
+
+ super.startDozing();
+ }
+
+ @Override
+ public void onDreamingStopped() {
+ if (DEBUG) Log.d(mTag, "onDreamingStopped isDozing=" + isDozing());
+ super.onDreamingStopped();
+
+ mDreaming = false;
+ mDozeHardware = null;
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ listenForTeaseSignals(false);
+ stopDozing();
+ dozingStopped();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ if (DEBUG) Log.d(mTag, "onDetachedFromWindow");
+ super.onDetachedFromWindow();
+
+ dozingStopped();
+ }
+
+ @Override
+ public void onDestroy() {
+ if (DEBUG) Log.d(mTag, "onDestroy");
+ super.onDestroy();
+
+ dozingStopped();
+ }
+
+ private void requestDoze() {
+ if (mHost != null) {
+ mHost.requestDoze(this);
+ }
+ }
+
+ private void requestTease() {
+ if (mHost != null) {
+ mHost.requestTease(this);
+ }
+ }
+
+ private void dozingStopped() {
+ if (mHost != null) {
+ mHost.dozingStopped(this);
+ }
+ }
+
+ private void listenForTeaseSignals(boolean listen) {
+ if (DEBUG) Log.d(mTag, "listenForTeaseSignals: " + listen);
+ if (mHost == null) return;
+ listenForSignificantMotion(listen);
+ if (listen) {
+ mContext.registerReceiver(mTeaseReceiver, new IntentFilter(TEASE_ACTION));
+ mTeaseReceiverRegistered = true;
+ mHost.addCallback(mHostCallback);
+ } else {
+ if (mTeaseReceiverRegistered) {
+ mContext.unregisterReceiver(mTeaseReceiver);
+ }
+ mTeaseReceiverRegistered = false;
+ mHost.removeCallback(mHostCallback);
+ }
+ }
+
+ private void listenForSignificantMotion(boolean listen) {
+ if (mSigMotionSensor == null) return;
+ if (listen) {
+ mSensors.requestTriggerSensor(mSigMotionListener, mSigMotionSensor);
+ } else {
+ mSensors.cancelTriggerSensor(mSigMotionListener, mSigMotionSensor);
+ }
+ }
+
+ private static String triggerEventToString(TriggerEvent event) {
+ if (event == null) return null;
+ final StringBuilder sb = new StringBuilder("TriggerEvent[")
+ .append(event.timestamp).append(',')
+ .append(event.sensor.getName());
+ if (event.values != null) {
+ for (int i = 0; i < event.values.length; i++) {
+ sb.append(',').append(event.values[i]);
+ }
+ }
+ return sb.append(']').toString();
+ }
+
+ private final TriggerEventListener mSigMotionListener = new TriggerEventListener() {
+ @Override
+ public void onTrigger(TriggerEvent event) {
+ if (DEBUG) Log.d(mTag, "sigMotion.onTrigger: " + triggerEventToString(event));
+ if (DEBUG) {
+ final Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+ if (v != null) {
+ v.vibrate(1000);
+ }
+ }
+ requestTease();
+ listenForSignificantMotion(true); // reregister, this sensor only fires once
+ }
+ };
+
+ private final BroadcastReceiver mTeaseReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) Log.d(mTag, "Received tease intent");
+ requestTease();
+ }
+ };
+
+ private final Host.Callback mHostCallback = new Host.Callback() {
+ @Override
+ public void onNewNotifications() {
+ if (DEBUG) Log.d(mTag, "onNewNotifications");
+ requestTease();
+ }
+ };
+
+ public interface Host {
+ void addCallback(Callback callback);
+ void removeCallback(Callback callback);
+ void requestDoze(DozeService dozeService);
+ void requestTease(DozeService dozeService);
+ void dozingStopped(DozeService dozeService);
+
+ public interface Callback {
+ void onNewNotifications();
+ }
+ }
+}