diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
new file mode 100644
index 0000000..bfcf2fc
--- /dev/null
+++ b/core/java/android/os/PowerManager.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2007 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.os;
+
+import android.util.Log;
+
+import com.android.internal.os.RuntimeInit;
+
+/**
+ * This class gives you control of the power state of the device.  
+ * 
+ * <p><b>Device battery life will be significantly affected by the use of this API.</b>  Do not
+ * acquire WakeLocks unless you really need them, use the minimum levels possible, and be sure
+ * to release it as soon as you can.
+ * 
+ * <p>You can obtain an instance of this class by calling 
+ * {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.
+ * 
+ * <p>The primary API you'll use is {@link #newWakeLock(int, String) newWakeLock()}.  This will
+ * create a {@link PowerManager.WakeLock} object.  You can then use methods on this object to 
+ * control the power state of the device.  In practice it's quite simple:
+ * 
+ * {@samplecode
+ * PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+ * PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
+ * wl.acquire();
+ *   ..screen will stay on during this section..
+ * wl.release();
+ * }
+ * 
+ * <p>The following flags are defined, with varying effects on system power.  <i>These flags are
+ * mutually exclusive - you may only specify one of them.</i>
+ * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
+ *
+ *     <thead>
+ *     <tr><th>Flag Value</th> 
+ *     <th>CPU</th> <th>Screen</th> <th>Keyboard</th></tr>
+ *     </thead>
+ *
+ *     <tbody>
+ *     <tr><th>{@link #PARTIAL_WAKE_LOCK}</th>
+ *         <td>On*</td> <td>Off</td> <td>Off</td> 
+ *     </tr>
+ *     
+ *     <tr><th>{@link #SCREEN_DIM_WAKE_LOCK}</th>
+ *         <td>On</td> <td>Dim</td> <td>Off</td> 
+ *     </tr>
+ *
+ *     <tr><th>{@link #SCREEN_BRIGHT_WAKE_LOCK}</th>
+ *         <td>On</td> <td>Bright</td> <td>Off</td> 
+ *     </tr>
+ *     
+ *     <tr><th>{@link #FULL_WAKE_LOCK}</th>
+ *         <td>On</td> <td>Bright</td> <td>Bright</td> 
+ *     </tr>
+ *     </tbody>
+ * </table>
+ * 
+ * <p>*<i>If you hold a partial wakelock, the CPU will continue to run, irrespective of any timers 
+ * and even after the user presses the power button.  In all other wakelocks, the CPU will run, but
+ * the user can still put the device to sleep using the power button.</i>
+ * 
+ * <p>In addition, you can add two more flags, which affect behavior of the screen only.  <i>These
+ * flags have no effect when combined with a {@link #PARTIAL_WAKE_LOCK}.</i>
+ * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
+ *
+ *     <thead>
+ *     <tr><th>Flag Value</th> <th>Description</th></tr>
+ *     </thead>
+ *
+ *     <tbody>
+ *     <tr><th>{@link #ACQUIRE_CAUSES_WAKEUP}</th>
+ *         <td>Normal wake locks don't actually turn on the illumination.  Instead, they cause
+ *         the illumination to remain on once it turns on (e.g. from user activity).  This flag
+ *         will force the screen and/or keyboard to turn on immediately, when the WakeLock is
+ *         acquired.  A typical use would be for notifications which are important for the user to
+ *         see immediately.</td> 
+ *     </tr>
+ *     
+ *     <tr><th>{@link #ON_AFTER_RELEASE}</th>
+ *         <td>If this flag is set, the user activity timer will be reset when the WakeLock is
+ *         released, causing the illumination to remain on a bit longer.  This can be used to 
+ *         reduce flicker if you are cycling between wake lock conditions.</td> 
+ *     </tr>
+ *     </tbody>
+ * </table>
+ * 
+ * 
+ */
+public class PowerManager
+{
+    private static final String TAG = "PowerManager";
+    
+    /**
+     * These internal values define the underlying power elements that we might
+     * want to control individually.  Eventually we'd like to expose them.
+     */
+    private static final int WAKE_BIT_CPU_STRONG = 1;
+    private static final int WAKE_BIT_CPU_WEAK = 2;
+    private static final int WAKE_BIT_SCREEN_DIM = 4;
+    private static final int WAKE_BIT_SCREEN_BRIGHT = 8;
+    private static final int WAKE_BIT_KEYBOARD_BRIGHT = 16;
+    
+    private static final int LOCK_MASK = WAKE_BIT_CPU_STRONG
+                                        | WAKE_BIT_CPU_WEAK
+                                        | WAKE_BIT_SCREEN_DIM
+                                        | WAKE_BIT_SCREEN_BRIGHT
+                                        | WAKE_BIT_KEYBOARD_BRIGHT;
+
+    /**
+     * Wake lock that ensures that the CPU is running.  The screen might
+     * not be on.
+     */
+    public static final int PARTIAL_WAKE_LOCK = WAKE_BIT_CPU_STRONG;
+
+    /**
+     * Wake lock that ensures that the screen and keyboard are on at
+     * full brightness.
+     */
+    public static final int FULL_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_BRIGHT 
+                                            | WAKE_BIT_KEYBOARD_BRIGHT;
+
+    /**
+     * Wake lock that ensures that the screen is on at full brightness;
+     * the keyboard backlight will be allowed to go off.
+     */
+    public static final int SCREEN_BRIGHT_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_BRIGHT;
+
+    /**
+     * Wake lock that ensures that the screen is on (but may be dimmed);
+     * the keyboard backlight will be allowed to go off.
+     */
+    public static final int SCREEN_DIM_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_DIM;
+
+    /**
+     * Normally wake locks don't actually wake the device, they just cause
+     * it to remain on once it's already on.  Think of the video player
+     * app as the normal behavior.  Notifications that pop up and want
+     * the device to be on are the exception; use this flag to be like them.
+     * <p> 
+     * Does not work with PARTIAL_WAKE_LOCKs.
+     */
+    public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000;
+
+    /**
+     * When this wake lock is released, poke the user activity timer
+     * so the screen stays on for a little longer.
+     * <p>
+     * Will not turn the screen on if it is not already on.  See {@link #ACQUIRE_CAUSES_WAKEUP}
+     * if you want that.
+     * <p>
+     * Does not work with PARTIAL_WAKE_LOCKs.
+     */
+    public static final int ON_AFTER_RELEASE = 0x20000000;
+    
+    /**
+     * Class lets you say that you need to have the device on.
+     *
+     * <p>Call release when you are done and don't need the lock anymore.
+     */
+    public class WakeLock
+    {
+        static final int RELEASE_WAKE_LOCK = 1;
+
+        Runnable mReleaser = new Runnable() {
+            public void run() {
+                release();
+            }
+        };
+	
+        int mFlags;
+        String mTag;
+        IBinder mToken;
+        int mCount = 0;
+        boolean mRefCounted = true;
+        boolean mHeld = false;
+
+        WakeLock(int flags, String tag)
+        {
+            switch (flags & LOCK_MASK) {
+            case PARTIAL_WAKE_LOCK:
+            case SCREEN_DIM_WAKE_LOCK:
+            case SCREEN_BRIGHT_WAKE_LOCK:
+            case FULL_WAKE_LOCK:
+                break;
+            default:
+                throw new IllegalArgumentException();
+            }
+
+            mFlags = flags;
+            mTag = tag;
+            mToken = new Binder();
+        }
+
+        /**
+         * Sets whether this WakeLock is ref counted.
+         *
+         * @param value true for ref counted, false for not ref counted.
+         */
+        public void setReferenceCounted(boolean value)
+        {
+            mRefCounted = value;
+        }
+
+        /**
+         * Makes sure the device is on at the level you asked when you created
+         * the wake lock.
+         */
+        public void acquire()
+        {
+            synchronized (mToken) {
+                if (!mRefCounted || mCount++ == 0) {
+                    try {
+                        mService.acquireWakeLock(mFlags, mToken, mTag);
+                    } catch (RemoteException e) {
+                    }
+                    mHeld = true;
+                }
+            }
+        }
+        
+        /**
+         * Makes sure the device is on at the level you asked when you created
+         * the wake lock. The lock will be released after the given timeout.
+         * 
+         * @param timeout Release the lock after the give timeout in milliseconds.
+         */
+        public void acquire(long timeout) {
+            acquire();
+            mHandler.postDelayed(mReleaser, timeout);
+        }
+        
+
+        /**
+         * Release your claim to the CPU or screen being on.
+         *
+         * <p>
+         * It may turn off shortly after you release it, or it may not if there
+         * are other wake locks held.
+         */
+        public void release()
+        {
+            synchronized (mToken) {
+                if (!mRefCounted || --mCount == 0) {
+                    try {
+                        mService.releaseWakeLock(mToken);
+                    } catch (RemoteException e) {
+                    }
+                    mHeld = false;
+                }
+                if (mCount < 0) {
+                    throw new RuntimeException("WakeLock under-locked " + mTag);
+                }
+            }
+        }
+
+        public boolean isHeld()
+        {
+            synchronized (mToken) {
+                return mHeld;
+            }
+        }
+
+        public String toString() {
+            synchronized (mToken) {
+                return "WakeLock{"
+                    + Integer.toHexString(System.identityHashCode(this))
+                    + " held=" + mHeld + ", refCount=" + mCount + "}";
+            }
+        }
+
+        @Override
+        protected void finalize() throws Throwable
+        {
+            synchronized (mToken) {
+                if (mHeld) {
+                    try {
+                        mService.releaseWakeLock(mToken);
+                    } catch (RemoteException e) {
+                    }
+                    RuntimeInit.crash(TAG, new Exception(
+                                "WakeLock finalized while still held: "+mTag));
+                }
+            }
+        }
+    }
+
+    /**
+     * Get a wake lock at the level of the flags parameter.  Call
+     * {@link WakeLock#acquire() acquire()} on the object to acquire the
+     * wake lock, and {@link WakeLock#release release()} when you are done.
+     *
+     * {@samplecode
+     *PowerManager pm = (PowerManager)mContext.getSystemService(
+     *                                          Context.POWER_SERVICE);
+     *PowerManager.WakeLock wl = pm.newWakeLock(
+     *                                      PowerManager.SCREEN_DIM_WAKE_LOCK
+     *                                      | PowerManager.ON_AFTER_RELEASE,
+     *                                      TAG);
+     *wl.acquire();
+     * // ...
+     *wl.release();
+     * }
+     *
+     * @param flags Combination of flag values defining the requested behavior of the WakeLock.
+     * @param tag Your class name (or other tag) for debugging purposes.
+     *
+     * @see WakeLock#acquire()
+     * @see WakeLock#release()
+     */
+    public WakeLock newWakeLock(int flags, String tag)
+    {
+        return new WakeLock(flags, tag);
+    }
+
+    /**
+     * User activity happened.
+     * <p>
+     * Turns the device from whatever state it's in to full on, and resets
+     * the auto-off timer.
+     *
+     * @param when is used to order this correctly with the wake lock calls.
+     *          This time should be in the {@link SystemClock#uptimeMillis
+     *          SystemClock.uptimeMillis()} time base.
+     * @param noChangeLights should be true if you don't want the lights to
+     *          turn on because of this event.  This is set when the power
+     *          key goes down.  We want the device to stay on while the button
+     *          is down, but we're about to turn off.  Otherwise the lights
+     *          flash on and then off and it looks weird.
+     */
+    public void userActivity(long when, boolean noChangeLights)
+    {
+        try {
+            mService.userActivity(when, noChangeLights);
+        } catch (RemoteException e) {
+        }
+    }
+
+   /**
+     * Force the device to go to sleep. Overrides all the wake locks that are
+     * held.
+     * 
+     * @param time is used to order this correctly with the wake lock calls. 
+     *          The time  should be in the {@link SystemClock#uptimeMillis 
+     *          SystemClock.uptimeMillis()} time base.
+     */
+    public void goToSleep(long time) 
+    {
+        try {
+            mService.goToSleep(time);
+        } catch (RemoteException e) {
+        }
+    }
+    
+    private PowerManager()
+    {
+    }
+
+    /**
+     * {@hide}
+     */
+    public PowerManager(IPowerManager service, Handler handler)
+    {
+        mService = service;
+        mHandler = handler;
+    }
+
+    /**
+     *  TODO: It would be nice to be able to set the poke lock here,
+     *  but I'm not sure what would be acceptable as an interface -
+     *  either a PokeLock object (like WakeLock) or, possibly just a
+     *  method call to set the poke lock. 
+     */
+    
+    IPowerManager mService;
+    Handler mHandler;
+}
+
