New Android Dreams architecture, disabled for now.

Rather than normal Activities (which have a host of problems
when used for this purpose), screen savers are now a
special kind of Service that can add views to its own
special window (TYPE_DREAM, in the SCREENSAVER layer).

Dreams are now launched by the power manager; whenever it is
about to turn the screen off, it asks the window manager if
it wants to run a screen saver instead. (http://b/5677408)

Also, the new config_enableDreams bool allows the entire
feature to be switched on or off in one place. It is
currently switched off (and the APIs are all @hidden).

Change-Id: Idfe9d430568471d15f4b463cb70586a899a331f7
diff --git a/core/java/android/service/dreams/Dream.java b/core/java/android/service/dreams/Dream.java
new file mode 100644
index 0000000..83464c9
--- /dev/null
+++ b/core/java/android/service/dreams/Dream.java
@@ -0,0 +1,392 @@
+/**
+ * 
+ */
+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;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.WindowManager;
+import android.view.WindowManagerImpl;
+
+/**
+ * @hide
+ *
+ */
+public class Dream extends Service implements Window.Callback {
+    private final static boolean DEBUG = true;
+    private final static String TAG = "Dream";
+    
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     * To be supported, the service must also require the
+     * {@link android.Manifest.permission#BIND_WALLPAPER} permission so
+     * that other applications can not abuse it.
+     */
+    @SdkConstant(SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.service.dreams.Dream";
+
+    private Window mWindow;
+
+    private WindowManager mWindowManager;
+    private IDreamManager mSandman;
+    
+    private boolean mInteractive;
+    
+    final Handler mHandler = new Handler();
+    
+    boolean mFinished = false;
+    
+    // begin Window.Callback methods
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        if (!mInteractive) { 
+            finish();
+            return true;
+        }
+        return mWindow.superDispatchKeyEvent(event);
+    }
+
+    @Override
+    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+        if (!mInteractive) { 
+            finish();
+            return true;
+        }
+        return mWindow.superDispatchKeyShortcutEvent(event);
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        if (!mInteractive) { 
+            finish();
+            return true;
+        }
+        return mWindow.superDispatchTouchEvent(event);
+    }
+
+    @Override
+    public boolean dispatchTrackballEvent(MotionEvent event) {
+        if (!mInteractive) { 
+            finish();
+            return true;
+        }
+        return mWindow.superDispatchTrackballEvent(event);
+    }
+
+    @Override
+    public boolean dispatchGenericMotionEvent(MotionEvent event) {
+        if (!mInteractive) { 
+            finish();
+            return true;
+        }
+        return mWindow.superDispatchGenericMotionEvent(event);
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        return false;
+    }
+
+    @Override
+    public View onCreatePanelView(int featureId) {
+        return null;
+    }
+
+    @Override
+    public boolean onCreatePanelMenu(int featureId, Menu menu) {
+        return false;
+    }
+
+    @Override
+    public boolean onPreparePanel(int featureId, View view, Menu menu) {
+        return false;
+    }
+
+    @Override
+    public boolean onMenuOpened(int featureId, Menu menu) {
+        return false;
+    }
+
+    @Override
+    public boolean onMenuItemSelected(int featureId, MenuItem item) {
+        return false;
+    }
+
+    @Override
+    public void onWindowAttributesChanged(LayoutParams attrs) {
+
+    }
+
+    @Override
+    public void onContentChanged() {
+
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        mWindow.addFlags(
+                WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+        );
+        lightsOut();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+    }
+
+    @Override
+    public void onPanelClosed(int featureId, Menu menu) {
+    }
+
+    @Override
+    public boolean onSearchRequested() {
+        return false;
+    }
+
+    @Override
+    public ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback callback) {
+        return null;
+    }
+
+    @Override
+    public void onActionModeStarted(ActionMode mode) {
+    }
+
+    @Override
+    public void onActionModeFinished(ActionMode mode) {
+    }
+    // end Window.Callback methods
+
+    public WindowManager getWindowManager() {
+        return mWindowManager;
+    }
+
+    public Window getWindow() {
+        return mWindow;
+    }
+    
+    /**
+     * Called when this Dream is constructed. Place your initialization here.
+     * 
+     * Subclasses must call through to the superclass implementation.
+     */
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        if (DEBUG) Slog.v(TAG, "Dream created on thread " + Thread.currentThread().getId());
+
+        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 
+     */
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        return super.onStartCommand(intent, flags, startId);
+    }
+    
+   /**
+     * Inflate a layout resource and set it to be the content view for this Dream.
+     * Behaves similarly to {@link android.app.Activity#setContentView(int)}.
+     *
+     * @param layoutResID Resource ID to be inflated.
+     * 
+     * @see #setContentView(android.view.View)
+     * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
+     */
+    public void setContentView(int layoutResID) {
+        getWindow().setContentView(layoutResID);
+    }
+
+    /**
+     * Set a view to be the content view for this Dream.
+     * Behaves similarly to {@link android.app.Activity#setContentView(android.view.View)},
+     * including using {@link ViewGroup.LayoutParams#MATCH_PARENT} as the layout height and width of the view.
+     * 
+     * @param view The desired content to display.
+     *
+     * @see #setContentView(int)
+     * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
+     */
+    public void setContentView(View view) {
+        getWindow().setContentView(view);
+    }
+
+    /**
+     * Set a view to be the content view for this Dream.
+     * Behaves similarly to 
+     * {@link android.app.Activity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}.
+     *
+     * @param view The desired content to display.
+     * @param params Layout parameters for the view.
+     *
+     * @see #setContentView(android.view.View)
+     * @see #setContentView(int)
+     */
+    public void setContentView(View view, ViewGroup.LayoutParams params) {
+        getWindow().setContentView(view, params);
+    }
+
+    /**
+     * Add a view to the Dream's window, leaving other content views in place.
+     * 
+     * @param view The desired content to display.
+     * @param params Layout parameters for the view.
+     */
+    public void addContentView(View view, ViewGroup.LayoutParams params) {
+        getWindow().addContentView(view, params);
+    }
+    
+    /**
+     * @param mInteractive the mInteractive to set
+     */
+    public void setInteractive(boolean mInteractive) {
+        this.mInteractive = mInteractive;
+    }
+
+    /**
+     * @return the mInteractive
+     */
+    public boolean isInteractive() {
+        return mInteractive;
+    }
+    
+    /** Convenience method for setting View.SYSTEM_UI_FLAG_LOW_PROFILE on the content view. */
+    protected void lightsOut() {
+        // turn the lights down low
+        final View v = mWindow.getDecorView();
+        if (v != null) {
+            v.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
+        }
+    }
+
+    /**
+     * Finds a view that was identified by the id attribute from the XML that
+     * was processed in {@link #onCreate}.
+     *
+     * @return The view if found or null otherwise.
+     */
+    public View findViewById(int id) {
+        return getWindow().findViewById(id);
+    }
+    
+    /**
+     * Called when this Dream is being removed from the screen and stopped.
+     */
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mWindowManager.removeView(mWindow.getDecorView());
+    }
+
+    /**
+     * Creates a new dream window, attaches the current content view, and shows it.
+     * 
+     * @param windowToken Binder to attach to the window to allow access to the correct window type.
+     * @hide
+     */
+    final /*package*/ void attach(IBinder windowToken) {
+        if (DEBUG) Slog.v(TAG, "Dream attached on thread " + Thread.currentThread().getId());
+        
+        mWindow = PolicyManager.makeNewWindow(this);
+        mWindow.setCallback(this);
+        mWindow.requestFeature(Window.FEATURE_NO_TITLE);
+        mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000));
+
+        if (DEBUG) Slog.v(TAG, "attaching window token: " + windowToken 
+                + " to window of type " + WindowManager.LayoutParams.TYPE_DREAM);
+
+        WindowManager.LayoutParams lp = mWindow.getAttributes();
+        lp.type = WindowManager.LayoutParams.TYPE_DREAM;
+        lp.token = windowToken;
+        lp.windowAnimations = com.android.internal.R.style.Animation_Dream;
+        
+        //WindowManagerImpl.getDefault().addView(mWindow.getDecorView(), lp);
+        
+        if (DEBUG) Slog.v(TAG, "created and attached window: " + mWindow);
+
+        mWindow.setWindowManager(null, windowToken, "dream", true);
+        mWindowManager = mWindow.getWindowManager();
+        
+        // now make it visible
+        mHandler.post(new Runnable(){
+            @Override
+            public void run() {
+                if (DEBUG) Slog.v(TAG, "Dream window added on thread " + Thread.currentThread().getId());
+                
+                getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes());
+            }});        
+    }
+    
+    /**
+     * Stop the dream and wake up.
+     * 
+     * After this method is called, the service will be stopped.
+     */
+    public void finish() {
+        if (mFinished) return;
+        try {
+            mSandman.awaken(); // assuming we were started by the DreamManager
+            stopSelf(); // if launched via any other means
+            mFinished = true;
+        } catch (RemoteException ex) {
+            // sigh
+        }
+    }
+
+    class IDreamServiceWrapper extends IDreamService.Stub {
+        public IDreamServiceWrapper() {
+        }
+
+        public void attach(IBinder windowToken) {
+            Dream.this.attach(windowToken);
+        }
+    }
+
+    /**
+     * Implement to return the implementation of the internal accessibility
+     * service interface.  Subclasses should not override.
+     */
+    @Override
+    public final IBinder onBind(Intent intent) {
+        return new IDreamServiceWrapper();
+    }
+}
diff --git a/core/java/android/service/dreams/DreamManagerService.java b/core/java/android/service/dreams/DreamManagerService.java
new file mode 100644
index 0000000..8712fa2
--- /dev/null
+++ b/core/java/android/service/dreams/DreamManagerService.java
@@ -0,0 +1,182 @@
+package android.service.dreams;
+
+import static android.provider.Settings.Secure.SCREENSAVER_COMPONENT;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import com.android.internal.view.IInputMethod;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+import android.view.IWindowManager;
+import android.view.WindowManager;
+
+/**
+ * 
+ * @hide
+ *
+ */
+
+public class DreamManagerService 
+        extends IDreamManager.Stub 
+        implements ServiceConnection
+{
+    private static final boolean DEBUG = true;
+    private static final String TAG = "DreamManagerService";
+    
+    final Object mLock = new Object[0];
+
+    private Context mContext;
+    private IWindowManager mIWindowManager;
+    
+    private ComponentName mCurrentDreamComponent;
+    private IDreamService mCurrentDream;
+    private Binder mCurrentDreamToken; 
+
+    public DreamManagerService(Context context) {
+        if (DEBUG) Slog.v(TAG, "DreamManagerService startup");
+        mContext = context;
+        mIWindowManager = IWindowManager.Stub.asInterface(
+                ServiceManager.getService(Context.WINDOW_SERVICE));
+    }
+
+    private void checkPermission(String permission) {
+        if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(permission)) {
+            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
+                    + ", must have permission " + permission);
+        }
+    }
+
+    // IDreamManager method
+    public void dream() {
+        ComponentName name = getDreamComponent();
+        if (name != null) {
+            synchronized (mLock) {
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    bindDreamComponentL(name, false);
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        }
+    }
+
+    // IDreamManager method
+    public void setDreamComponent(ComponentName name) {
+        Settings.Secure.putString(mContext.getContentResolver(), SCREENSAVER_COMPONENT, name.flattenToString());
+    }
+    
+    // IDreamManager method
+    public ComponentName getDreamComponent() {
+        // TODO(dsandler) don't load this every time, watch the value  
+        String component = Settings.Secure.getString(mContext.getContentResolver(), SCREENSAVER_COMPONENT);
+        if (component == null) {
+            component = mContext.getResources().getString(
+                com.android.internal.R.string.config_defaultDreamComponent);
+        }
+        if (component != null) {
+            return ComponentName.unflattenFromString(component);
+        } else {
+            return null;
+        }
+    }
+    
+    // IDreamManager method
+    public void testDream(ComponentName name) {
+        if (DEBUG) Slog.v(TAG, "startDream name=" + name
+                + " pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
+//        checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
+        synchronized (mLock) {
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                bindDreamComponentL(name, true);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    // IDreamManager method
+    public void awaken() {
+        if (DEBUG) Slog.v(TAG, "awaken()");
+        synchronized (mLock) {
+            if (mCurrentDream != null) {
+                mContext.unbindService(this);
+            }
+        }
+    }
+
+    public void bindDreamComponentL(ComponentName componentName, boolean test) {
+        if (DEBUG) Slog.v(TAG, "bindDreamComponent: componentName=" + componentName
+                + " pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
+
+        Intent intent = new Intent(Intent.ACTION_MAIN)
+            .setComponent(componentName)
+            .addFlags(
+                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 {
+            if (DEBUG) Slog.v(TAG, "Adding window token: " + mCurrentDreamToken 
+                    + " for window type: " + WindowManager.LayoutParams.TYPE_DREAM);
+            mIWindowManager.addWindowToken(mCurrentDreamToken,
+                    WindowManager.LayoutParams.TYPE_DREAM);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Unable to add window token. Proceed at your own risk.");
+        }
+        
+    }
+
+    @Override
+    public void onServiceConnected(ComponentName name, IBinder service) {
+        if (DEBUG) Slog.v(TAG, "connected to dream: " + name + " binder=" + service + " thread=" + Thread.currentThread().getId());
+
+        mCurrentDream = IDreamService.Stub.asInterface(service);
+        try {
+            if (DEBUG) Slog.v(TAG, "attaching with token:" + mCurrentDreamToken);
+            mCurrentDream.attach(mCurrentDreamToken);
+        } catch (RemoteException ex) {
+            Slog.w(TAG, "Unable to send window token to dream:" + ex);
+        }
+    }
+
+    @Override
+    public void onServiceDisconnected(ComponentName name) {
+        if (DEBUG) Slog.v(TAG, "disconnected: " + name + " service: " + mCurrentDream);
+        mCurrentDream = null;
+        mCurrentDreamToken = null;
+    }
+    
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Dreamland:");
+        pw.print("  component="); pw.println(mCurrentDreamComponent);
+        pw.print("  token="); pw.println(mCurrentDreamToken);
+        pw.print("  dream="); pw.println(mCurrentDream);
+    }
+
+    public void systemReady() {
+        if (DEBUG) Slog.v(TAG, "ready to dream!");
+    }
+
+}
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
new file mode 100644
index 0000000..7225013
--- /dev/null
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -0,0 +1,30 @@
+/**
+ * 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 android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.content.ComponentName;
+
+/** @hide */
+interface IDreamManager {
+    void dream();
+    void awaken();
+    void setDreamComponent(in ComponentName componentName);
+    ComponentName getDreamComponent();
+    void testDream(in ComponentName componentName);
+}
\ No newline at end of file
diff --git a/core/java/android/service/dreams/IDreamService.aidl b/core/java/android/service/dreams/IDreamService.aidl
new file mode 100644
index 0000000..1bb241a
--- /dev/null
+++ b/core/java/android/service/dreams/IDreamService.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+/**
+ * @hide
+ */
+oneway interface IDreamService {
+    void attach(IBinder windowToken);
+}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f3ef329..bc310b0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -423,6 +423,12 @@
         public static final int TYPE_HIDDEN_NAV_CONSUMER = FIRST_SYSTEM_WINDOW+22;
 
         /**
+         * Window type: Dreams (screen saver) window, just above keyguard.
+         * @hide
+         */
+        public static final int TYPE_DREAM = FIRST_SYSTEM_WINDOW+23;
+
+        /**
          * End of types of system windows.
          */
         public static final int LAST_SYSTEM_WINDOW      = 2999;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 491cd67..66bdc5d 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1049,6 +1049,31 @@
     public void lockNow();
 
     /**
+     * Check to see if a screensaver should be run instead of powering off the screen on timeout. 
+     * 
+     * @return true if the screensaver should run, false if the screen should turn off.
+     * 
+     * @hide
+     */
+    public boolean isScreenSaverEnabled();
+
+    /**
+     * Start the screensaver (if it is enabled and not yet running).
+     * 
+     * @return Whether the screensaver was successfully started.
+     * 
+     * @hide
+     */
+    public boolean startScreenSaver();
+
+    /**
+     * Stop the screensaver if it is running.
+     * 
+     * @hide
+     */
+    public void stopScreenSaver();
+
+    /**
      * Print the WindowManagerPolicy's state into the given stream.
      *
      * @param prefix Text to print at the front of each line.
diff --git a/core/res/res/anim/slow_fade_in.xml b/core/res/res/anim/slow_fade_in.xml
new file mode 100644
index 0000000..21a2c78
--- /dev/null
+++ b/core/res/res/anim/slow_fade_in.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/fade_in.xml
+**
+** Copyright 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.
+*/
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@interpolator/decelerate_quad"
+        android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:duration="1000" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 4fde018..e80e30a 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -837,6 +837,8 @@
     <!-- Name of the wimax state tracker clas -->
     <string name="config_wimaxStateTrackerClassname" translatable="false"></string>
 
+    <!-- enable screen saver feature -->
+    <bool name="config_enableDreams">false</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/core/res/res/values/public.xml b/core/res/res/values/public.xml
index ca0e913..cbfc1a4 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1110,6 +1110,7 @@
   <java-symbol type="style" name="Animation.PopupWindow" />
   <java-symbol type="style" name="Animation.TypingFilter" />
   <java-symbol type="style" name="Animation.TypingFilterRestore" />
+  <java-symbol type="style" name="Animation.Dream" />
   <java-symbol type="style" name="Theme.DeviceDefault.Dialog.Alert" />
   <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" />
   <java-symbol type="style" name="Theme.Dialog.Alert" />
@@ -1262,7 +1263,6 @@
   <java-symbol type="layout" name="screen_title_icons" />
   <java-symbol type="string" name="abbrev_wday_month_day_no_year" />
   <java-symbol type="string" name="android_upgrading_title" />
-  <java-symbol type="string" name="config_defaultDreamComponent" />
   <java-symbol type="string" name="faceunlock_multiple_failures" />
   <java-symbol type="string" name="global_action_power_off" />
   <java-symbol type="string" name="global_actions_airplane_mode_off_status" />
@@ -1480,6 +1480,8 @@
   <java-symbol type="style" name="Theme.Dialog.AppError" />
   <java-symbol type="style" name="Theme.Toast" />
   <java-symbol type="xml" name="storage_list" />
+  <java-symbol type="bool" name="config_enableDreams" />
+  <java-symbol type="string" name="config_defaultDreamComponent" />
 
   <!-- From SystemUI -->
   <java-symbol type="anim" name="push_down_in" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index baeb9cc..2eeb067 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -219,6 +219,12 @@
         <item name="windowExitAnimation">@anim/fade_out</item>
     </style>
 
+    <!-- Window animations for screen savers. {@hide} -->
+    <style name="Animation.Dream">
+        <item name="windowEnterAnimation">@anim/slow_fade_in</item>
+        <item name="windowExitAnimation">@anim/fast_fade_out</item>
+    </style>
+
     <!-- Status Bar Styles -->
     <style name="TextAppearance.StatusBar">
         <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>