Re-enable dreams: frameworks/base
Enable feature in config. Expose Dream in public api for unbundled apps.
Unhide package. Add isDreaming() method to service.
Re-arrange the Dream api a bit. (use onStart as hook for subclasses).
Coordinate properly with power manager.
Replace old dock mode (don't fire old intent).
Change-Id: I1318d20cc1613e5d862f2913f2fcdc9719302cf7
Bug: 6921930
diff --git a/api/current.txt b/api/current.txt
index 4b43318..cc67e89 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19927,6 +19927,50 @@
}
+package android.service.dreams {
+
+ public class Dream extends android.app.Service implements android.view.Window.Callback {
+ ctor public Dream();
+ method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
+ method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
+ method public boolean dispatchKeyEvent(android.view.KeyEvent);
+ method public boolean dispatchKeyShortcutEvent(android.view.KeyEvent);
+ method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+ method public boolean dispatchTouchEvent(android.view.MotionEvent);
+ method public boolean dispatchTrackballEvent(android.view.MotionEvent);
+ method public android.view.View findViewById(int);
+ method public void finish();
+ method public android.view.Window getWindow();
+ method public android.view.WindowManager getWindowManager();
+ method public boolean isInteractive();
+ method protected void lightsOut();
+ method public void onActionModeFinished(android.view.ActionMode);
+ method public void onActionModeStarted(android.view.ActionMode);
+ method public void onAttachedToWindow();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ method public void onContentChanged();
+ method public boolean onCreatePanelMenu(int, android.view.Menu);
+ method public android.view.View onCreatePanelView(int);
+ method public void onDetachedFromWindow();
+ method public boolean onMenuItemSelected(int, android.view.MenuItem);
+ method public boolean onMenuOpened(int, android.view.Menu);
+ method public void onPanelClosed(int, android.view.Menu);
+ method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+ method public boolean onSearchRequested();
+ method public void onStart();
+ method public final int onStartCommand(android.content.Intent, int, int);
+ method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
+ method public void onWindowFocusChanged(boolean);
+ method public android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback);
+ method public void setContentView(int);
+ method public void setContentView(android.view.View);
+ method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
+ method public void setInteractive(boolean);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.dreams.Dream";
+ }
+
+}
+
package android.service.textservice {
public abstract class SpellCheckerService extends android.app.Service {
diff --git a/core/java/android/service/dreams/Dream.java b/core/java/android/service/dreams/Dream.java
index 83464c9..9a903e4 100644
--- a/core/java/android/service/dreams/Dream.java
+++ b/core/java/android/service/dreams/Dream.java
@@ -1,26 +1,31 @@
/**
- *
+ * Copyright (C) 2012 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 android.service.dreams;
-import com.android.internal.policy.PolicyManager;
-
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.Service;
-import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
import android.graphics.drawable.ColorDrawable;
-import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Slog;
import android.view.ActionMode;
-import android.view.IWindowManager;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
@@ -28,14 +33,14 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
+import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
-import android.view.WindowManager;
-import android.view.WindowManagerImpl;
+
+import com.android.internal.policy.PolicyManager;
/**
- * @hide
- *
+ * Extend this class to implement a custom screensaver.
*/
public class Dream extends Service implements Window.Callback {
private final static boolean DEBUG = true;
@@ -61,7 +66,7 @@
final Handler mHandler = new Handler();
boolean mFinished = false;
-
+
// begin Window.Callback methods
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
@@ -210,19 +215,14 @@
mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams"));
}
-
+
/**
- * Called when this Dream is started. Place your initialization here.
- *
- * Subclasses must call through to the superclass implementation.
- *
- * XXX(dsandler) Might want to make this final and have a different method for clients to override
+ * Called when this Dream is started.
*/
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- return super.onStartCommand(intent, flags, startId);
+ public void onStart() {
+ // hook for subclasses
}
-
+
/**
* Inflate a layout resource and set it to be the content view for this Dream.
* Behaves similarly to {@link android.app.Activity#setContentView(int)}.
@@ -351,9 +351,12 @@
@Override
public void run() {
if (DEBUG) Slog.v(TAG, "Dream window added on thread " + Thread.currentThread().getId());
-
+
getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes());
- }});
+
+ // start it up
+ onStart();
+ }});
}
/**
diff --git a/core/java/android/service/dreams/DreamManagerService.java b/core/java/android/service/dreams/DreamManagerService.java
index 4a14ced..d6b38a1 100644
--- a/core/java/android/service/dreams/DreamManagerService.java
+++ b/core/java/android/service/dreams/DreamManagerService.java
@@ -114,11 +114,19 @@
if (DEBUG) Slog.v(TAG, "awaken()");
synchronized (mLock) {
if (mCurrentDream != null) {
+ if (DEBUG) Slog.v(TAG, "disconnecting: " + mCurrentDreamComponent + " service: " + mCurrentDream);
mContext.unbindService(this);
+ mCurrentDream = null;
+ mCurrentDreamToken = null;
}
}
}
+ // IDreamManager method
+ public boolean isDreaming() {
+ return mCurrentDream != null;
+ }
+
public void bindDreamComponentL(ComponentName componentName, boolean test) {
if (DEBUG) Slog.v(TAG, "bindDreamComponent: componentName=" + componentName
+ " pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
@@ -129,11 +137,7 @@
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
)
.putExtra("android.dreams.TEST", test);
-
- if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE)) {
- Slog.w(TAG, "unable to bind service: " + componentName);
- return;
- }
+
mCurrentDreamComponent = componentName;
mCurrentDreamToken = new Binder();
try {
@@ -145,6 +149,9 @@
Slog.w(TAG, "Unable to add window token. Proceed at your own risk.");
}
+ if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE)) {
+ Slog.w(TAG, "unable to bind service: " + componentName);
+ }
}
@Override
@@ -163,8 +170,7 @@
@Override
public void onServiceDisconnected(ComponentName name) {
if (DEBUG) Slog.v(TAG, "disconnected: " + name + " service: " + mCurrentDream);
- mCurrentDream = null;
- mCurrentDreamToken = null;
+ // Only happens in exceptional circumstances
}
@Override
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
index 7225013..b64dd8f 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -27,4 +27,5 @@
void setDreamComponent(in ComponentName componentName);
ComponentName getDreamComponent();
void testDream(in ComponentName componentName);
+ boolean isDreaming();
}
\ No newline at end of file
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 39129e5..b752471 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -852,7 +852,7 @@
<string name="config_wimaxStateTrackerClassname" translatable="false"></string>
<!-- enable screen saver feature -->
- <bool name="config_enableDreams">false</bool>
+ <bool name="config_enableDreams">true</bool>
<!-- Name of screensaver components to look for if none has been chosen by the user -->
<string name="config_defaultDreamComponent" translatable="false">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 97b4cb5..215f597 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1132,7 +1132,7 @@
com.android.internal.R.bool.config_enableDreams);
mScreenSaverEnabledByUser = 0 != Settings.Secure.getInt(resolver,
- Settings.Secure.SCREENSAVER_ENABLED, 1);
+ Settings.Secure.SCREENSAVER_ENABLED, 0);
if (SEPARATE_TIMEOUT_FOR_SCREEN_SAVER) {
mScreenSaverTimeout = Settings.Secure.getInt(resolver,
@@ -4076,7 +4076,9 @@
if (dm == null) return;
try {
- if (localLOGV) Log.v(TAG, "startScreenSaver: awakening...");
+ if (!dm.isDreaming()) return;
+
+ if (localLOGV) Log.v(TAG, "stopScreenSaver: awakening...");
dm.awaken();
} catch (RemoteException ex) {
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index e7dac72..8bac52c 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -29,9 +29,12 @@
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UEventObserver;
import android.provider.Settings;
+import android.service.dreams.IDreamManager;
import android.util.Log;
import android.util.Slog;
@@ -194,7 +197,29 @@
}
}
- mContext.sendStickyBroadcast(intent);
+ IDreamManager mgr = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams"));
+ if (mgr != null) {
+ // dreams feature enabled
+ boolean undocked = mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED;
+ if (undocked) {
+ try {
+ if (mgr.isDreaming()) {
+ mgr.awaken();
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Unable to awaken!", e);
+ }
+ } else {
+ try {
+ mgr.dream();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Unable to dream!", e);
+ }
+ }
+ } else {
+ // dreams feature not enabled, send legacy intent
+ mContext.sendStickyBroadcast(intent);
+ }
}
break;
}
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 453c7a4..cb6db3c 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -424,6 +424,11 @@
forceUserActivityLocked();
}
}
+
+ // stop the screensaver if we're now unplugged
+ if (mPolicy != null) {
+ mPolicy.stopScreenSaver();
+ }
}
}
}
@@ -1826,7 +1831,7 @@
final boolean stateChanged = mPowerState != newState;
if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {
- if (mPolicy != null && mPolicy.isScreenSaverEnabled()) {
+ if (mPolicy != null && mPolicy.isScreenSaverEnabled() && mIsPowered) {
if (DEBUG) {
Slog.d(TAG, "setPowerState: running screen saver instead of turning off screen");
}
@@ -1922,6 +1927,13 @@
} else {
err = 0;
}
+
+ // stop the screensaver if user turned screen off
+ if (stateChanged && reason == WindowManagerPolicy.OFF_BECAUSE_OF_USER) {
+ if (mPolicy != null) {
+ mPolicy.stopScreenSaver();
+ }
+ }
}
} else if (stateChanged) {
// Screen on/off didn't change, but lights may have.