diff --git a/core/java/android/os/AsyncResult.java b/core/java/android/os/AsyncResult.java
new file mode 100644
index 0000000..5bad09d
--- /dev/null
+++ b/core/java/android/os/AsyncResult.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2006 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.os.Message;
+
+/** @hide */
+public class AsyncResult
+{
+
+    /*************************** Instance Variables **************************/
+
+    // Expect either exception or result to be null
+    public Object userObj;
+    public Throwable exception;
+    public Object result;
+
+    /***************************** Class Methods *****************************/
+
+    /** Saves and sets m.obj */
+    public static AsyncResult 
+    forMessage(Message m, Object r, Throwable ex)
+    {
+        AsyncResult ret;
+
+        ret = new AsyncResult (m.obj, r, ex);
+
+        m.obj = ret; 
+
+        return ret;
+    }
+
+    /** Saves and sets m.obj */
+    public static AsyncResult 
+    forMessage(Message m)
+    {
+        AsyncResult ret;
+
+        ret = new AsyncResult (m.obj, null, null);
+
+        m.obj = ret; 
+
+        return ret;
+    }
+
+    /** please note, this sets m.obj to be this */
+    public 
+    AsyncResult (Object uo, Object r, Throwable ex)
+    {
+        userObj = uo;
+        result = r;
+        exception = ex;
+    }
+}
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
new file mode 100644
index 0000000..ee4e897
--- /dev/null
+++ b/core/java/android/os/AsyncTask.java
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2008 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 java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * <p>AsyncTask enables proper and easy use of the UI thread. This class allows to
+ * perform background operations and publish results on the UI thread without
+ * having to manipulate threads and/or handlers.</p>
+ *
+ * <p>An asynchronous task is defined by a computation that runs on a background thread and
+ * whose result is published on the UI thread. An asynchronous task is defined by 3 generic
+ * types, called <code>Params</code>, <code>Progress</code> and <code>Result</code>,
+ * and 4 steps, called <code>begin</code>, <code>doInBackground</code>,
+ * <code>processProgress<code> and <code>end</code>.</p>
+ *
+ * <h2>Usage</h2>
+ * <p>AsyncTask must be subclassed to be used. The subclass will override at least
+ * one method ({@link #doInBackground}), and most often will override a
+ * second one ({@link #onPostExecute}.)</p>
+ *
+ * <p>Here is an example of subclassing:</p>
+ * <pre class="prettyprint">
+ * private class DownloadFilesTask extends AsyncTask&lt;URL, Integer, Long&gt; {
+ *     protected Long doInBackground(URL... urls) {
+ *         int count = urls.length;
+ *         long totalSize = 0;
+ *         for (int i = 0; i < count; i++) {
+ *             totalSize += Downloader.downloadFile(urls[i]);
+ *             publishProgress((int) ((i / (float) count) * 100));
+ *         }
+ *         return totalSize;
+ *     }
+ *
+ *     protected void onProgressUpdate(Integer... progress) {
+ *         setProgressPercent(progress[0]);
+ *     }
+ *
+ *     protected void onPostExecute(Long result) {
+ *         showDialog("Downloaded " + result + " bytes");
+ *     }
+ * }
+ * </pre>
+ *
+ * <p>Once created, a task is executed very simply:</p>
+ * <pre class="prettyprint">
+ * new DownloadFilesTask().execute(url1, url2, url3);
+ * </pre>
+ *
+ * <h2>AsyncTask's generic types</h2>
+ * <p>The three types used by an asynchronous task are the following:</p>
+ * <ol>
+ *     <li><code>Params</code>, the type of the parameters sent to the task upon
+ *     execution.</li>
+ *     <li><code>Progress</code>, the type of the progress units published during
+ *     the background computation.</li>
+ *     <li><code>Result</code>, the type of the result of the background
+ *     computation.</li>
+ * </ol>
+ * <p>Not all types are always used by am asynchronous task. To mark a type as unused,
+ * simply use the type {@link Void}:</p>
+ * <pre>
+ * private class MyTask extends AsyncTask<Void, Void, Void) { ... }
+ * </pre>
+ *
+ * <h2>The 4 steps</h2>
+ * <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
+ * <ol>
+ *     <li>{@link #onPreExecute()}, invoked on the UI thread immediately after the task
+ *     is executed. This step is normally used to setup the task, for instance by
+ *     showing a progress bar in the user interface.</li>
+ *     <li>{@link #doInBackground}, invoked on the background thread
+ *     immediately after {@link #onPreExecute()} finishes executing. This step is used
+ *     to perform background computation that can take a long time. The parameters
+ *     of the asynchronous task are passed to this step. The result of the computation must
+ *     be returned by this step and will be passed back to the last step. This step
+ *     can also use {@link #publishProgress} to publish one or more units
+ *     of progress. These values are published on the UI thread, in the
+ *     {@link #onProgressUpdate} step.</li>
+ *     <li>{@link #onProgressUpdate}, invoked on the UI thread after a
+ *     call to {@link #publishProgress}. The timing of the execution is
+ *     undefined. This method is used to display any form of progress in the user
+ *     interface while the background computation is still executing. For instance,
+ *     it can be used to animate a progress bar or show logs in a text field.</li>
+ *     <li>{@link #onPostExecute}, invoked on the UI thread after the background
+ *     computation finishes. The result of the background computation is passed to
+ *     this step as a parameter.</li>
+ * </ol>
+ *
+ * <h2>Threading rules</h2>
+ * <p>There are a few threading rules that must be followed for this class to
+ * work properly:</p>
+ * <ul>
+ *     <li>The task instance must be created on the UI thread.</li>
+ *     <li>{@link #execute} must be invoked on the UI thread.</li>
+ *     <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
+ *     {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
+ *     <li>The task can be executed only once (an exception will be thrown if
+ *     a second execution is attempted.)</li>
+ * </ul>
+ */
+public abstract class AsyncTask<Params, Progress, Result> {
+    private static final String LOG_TAG = "AsyncTask";
+
+    private static final int CORE_POOL_SIZE = 1;
+    private static final int MAXIMUM_POOL_SIZE = 10;
+    private static final int KEEP_ALIVE = 10;
+
+    private static final BlockingQueue<Runnable> sWorkQueue =
+            new LinkedBlockingQueue<Runnable>(MAXIMUM_POOL_SIZE);
+
+    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
+        private final AtomicInteger mCount = new AtomicInteger(1);
+
+        public Thread newThread(Runnable r) {
+            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
+        }
+    };
+
+    private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
+            MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
+
+    private static final int MESSAGE_POST_RESULT = 0x1;
+    private static final int MESSAGE_POST_PROGRESS = 0x2;
+    private static final int MESSAGE_POST_CANCEL = 0x3;
+
+    private static final InternalHandler sHandler = new InternalHandler();
+
+    private final WorkerRunnable<Params, Result> mWorker;
+    private final FutureTask<Result> mFuture;
+
+    private volatile Status mStatus = Status.PENDING;
+
+    /**
+     * Indicates the current status of the task. Each status will be set only once
+     * during the lifetime of a task.
+     */
+    public enum Status {
+        /**
+         * Indicates that the task has not been executed yet.
+         */
+        PENDING,
+        /**
+         * Indicates that the task is running.
+         */
+        RUNNING,
+        /**
+         * Indicates that {@link AsyncTask#onPostExecute} has finished.
+         */
+        FINISHED,
+    }
+
+    /**
+     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
+     */
+    public AsyncTask() {
+        mWorker = new WorkerRunnable<Params, Result>() {
+            public Result call() throws Exception {
+                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+                return doInBackground(mParams);
+            }
+        };
+
+        mFuture = new FutureTask<Result>(mWorker) {
+            @Override
+            protected void done() {
+                Message message;
+                Result result = null;
+
+                try {
+                    result = get();
+                } catch (InterruptedException e) {
+                    android.util.Log.w(LOG_TAG, e);
+                } catch (ExecutionException e) {
+                    throw new RuntimeException("An error occured while executing doInBackground()",
+                            e.getCause());
+                } catch (CancellationException e) {
+                    message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
+                            new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
+                    message.sendToTarget();
+                    return;
+                } catch (Throwable t) {
+                    throw new RuntimeException("An error occured while executing "
+                            + "doInBackground()", t);
+                }
+
+                message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
+                        new AsyncTaskResult<Result>(AsyncTask.this, result));
+                message.sendToTarget();
+            }
+        };
+    }
+
+    /**
+     * Returns the current status of this task.
+     *
+     * @return The current status.
+     */
+    public final Status getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * Override this method to perform a computation on a background thread. The
+     * specified parameters are the parameters passed to {@link #execute}
+     * by the caller of this task.
+     *
+     * This method can call {@link #publishProgress} to publish updates
+     * on the UI thread.
+     *
+     * @param params The parameters of the task.
+     *
+     * @return A result, defined by the subclass of this task.
+     *
+     * @see #onPreExecute()
+     * @see #onPostExecute
+     * @see #publishProgress
+     */
+    protected abstract Result doInBackground(Params... params);
+
+    /**
+     * Runs on the UI thread before {@link #doInBackground}.
+     *
+     * @see #onPostExecute
+     * @see #doInBackground
+     */
+    protected void onPreExecute() {
+    }
+
+    /**
+     * Runs on the UI thread after {@link #doInBackground}. The
+     * specified result is the value returned by {@link #doInBackground}
+     * or null if the task was cancelled or an exception occured.
+     *
+     * @param result The result of the operation computed by {@link #doInBackground}.
+     *
+     * @see #onPreExecute
+     * @see #doInBackground
+     */
+    @SuppressWarnings({"UnusedDeclaration"})
+    protected void onPostExecute(Result result) {
+    }
+
+    /**
+     * Runs on the UI thread after {@link #publishProgress} is invoked.
+     * The specified values are the values passed to {@link #publishProgress}.
+     *
+     * @param values The values indicating progress.
+     *
+     * @see #publishProgress
+     * @see #doInBackground
+     */
+    @SuppressWarnings({"UnusedDeclaration"})
+    protected void onProgressUpdate(Progress... values) {
+    }
+
+    /**
+     * Runs on the UI thread after {@link #cancel(boolean)} is invoked.
+     *
+     * @see #cancel(boolean)
+     * @see #isCancelled()
+     */
+    protected void onCancelled() {
+    }
+
+    /**
+     * Returns <tt>true</tt> if this task was cancelled before it completed
+     * normally.
+     *
+     * @return <tt>true</tt> if task was cancelled before it completed
+     *
+     * @see #cancel(boolean)
+     */
+    public final boolean isCancelled() {
+        return mFuture.isCancelled();
+    }
+
+    /**
+     * Attempts to cancel execution of this task.  This attempt will
+     * fail if the task has already completed, already been cancelled,
+     * or could not be cancelled for some other reason. If successful,
+     * and this task has not started when <tt>cancel</tt> is called,
+     * this task should never run.  If the task has already started,
+     * then the <tt>mayInterruptIfRunning</tt> parameter determines
+     * whether the thread executing this task should be interrupted in
+     * an attempt to stop the task.
+     *
+     * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
+     *        task should be interrupted; otherwise, in-progress tasks are allowed
+     *        to complete.
+     *
+     * @return <tt>false</tt> if the task could not be cancelled,
+     *         typically because it has already completed normally;
+     *         <tt>true</tt> otherwise
+     *
+     * @see #isCancelled()
+     * @see #onCancelled()
+     */
+    public final boolean cancel(boolean mayInterruptIfRunning) {
+        return mFuture.cancel(mayInterruptIfRunning);
+    }
+
+    /**
+     * Waits if necessary for the computation to complete, and then
+     * retrieves its result.
+     *
+     * @return The computed result.
+     *
+     * @throws CancellationException If the computation was cancelled.
+     * @throws ExecutionException If the computation threw an exception.
+     * @throws InterruptedException If the current thread was interrupted
+     *         while waiting.
+     */
+    public final Result get() throws InterruptedException, ExecutionException {
+        return mFuture.get();
+    }
+
+    /**
+     * Waits if necessary for at most the given time for the computation
+     * to complete, and then retrieves its result.
+     *
+     * @param timeout Time to wait before cancelling the operation.
+     * @param unit The time unit for the timeout.
+     *
+     * @return The computed result.
+     *
+     * @throws CancellationException If the computation was cancelled.
+     * @throws ExecutionException If the computation threw an exception.
+     * @throws InterruptedException If the current thread was interrupted
+     *         while waiting.
+     * @throws TimeoutException If the wait timed out.
+     */
+    public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
+            ExecutionException, TimeoutException {
+        return mFuture.get(timeout, unit);
+    }
+
+    /**
+     * Executes the task with the specified parameters. The task returns
+     * itself (this) so that the caller can keep a reference to it.
+     *
+     * This method must be invoked on the UI thread.
+     *
+     * @param params The parameters of the task.
+     *
+     * @return This instance of AsyncTask.
+     *
+     * @throws IllegalStateException If {@link #getStatus()} returns either
+     *         {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
+     */
+    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
+        if (mStatus != Status.PENDING) {
+            switch (mStatus) {
+                case RUNNING:
+                    throw new IllegalStateException("Cannot execute task:"
+                            + " the task is already running.");
+                case FINISHED:
+                    throw new IllegalStateException("Cannot execute task:"
+                            + " the task has already been executed "
+                            + "(a task can be executed only once)");
+            }
+        }
+
+        mStatus = Status.RUNNING;
+
+        onPreExecute();
+
+        mWorker.mParams = params;
+        sExecutor.execute(mFuture);
+
+        return this;
+    }
+
+    /**
+     * This method can be invoked from {@link #doInBackground} to
+     * publish updates on the UI thread while the background computation is
+     * still running. Each call to this method will trigger the execution of
+     * {@link #onProgressUpdate} on the UI thread.
+     *
+     * @param values The progress values to update the UI with.
+     *
+     * @see #onProgressUpdate
+     * @see #doInBackground
+     */
+    protected final void publishProgress(Progress... values) {
+        sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
+                new AsyncTaskResult<Progress>(this, values)).sendToTarget();
+    }
+
+    private void finish(Result result) {
+        onPostExecute(result);
+        mStatus = Status.FINISHED;
+    }
+
+    private static class InternalHandler extends Handler {
+        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
+            switch (msg.what) {
+                case MESSAGE_POST_RESULT:
+                    // There is only one result
+                    result.mTask.finish(result.mData[0]);
+                    break;
+                case MESSAGE_POST_PROGRESS:
+                    result.mTask.onProgressUpdate(result.mData);
+                    break;
+                case MESSAGE_POST_CANCEL:
+                    result.mTask.onCancelled();
+                    break;
+            }
+        }
+    }
+
+    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
+        Params[] mParams;
+    }
+
+    @SuppressWarnings({"RawUseOfParameterizedType"})
+    private static class AsyncTaskResult<Data> {
+        final AsyncTask mTask;
+        final Data[] mData;
+
+        AsyncTaskResult(AsyncTask task, Data... data) {
+            mTask = task;
+            mData = data;
+        }
+    }
+}
diff --git a/core/java/android/os/BadParcelableException.java b/core/java/android/os/BadParcelableException.java
new file mode 100644
index 0000000..a1c5bb2
--- /dev/null
+++ b/core/java/android/os/BadParcelableException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 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.AndroidRuntimeException;
+
+/**
+ * The object you are calling has died, because its hosting process
+ * no longer exists.
+ */
+public class BadParcelableException extends AndroidRuntimeException {
+    public BadParcelableException(String msg) {
+        super(msg);
+    }
+    public BadParcelableException(Exception cause) {
+        super(cause);
+    }
+}
diff --git a/core/java/android/os/Base64Utils.java b/core/java/android/os/Base64Utils.java
new file mode 100644
index 0000000..684a469
--- /dev/null
+++ b/core/java/android/os/Base64Utils.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * {@hide}
+ */
+public class Base64Utils
+{
+    // TODO add encode api here if possible
+    
+    public static byte [] decodeBase64(String data) {
+        return decodeBase64Native(data);
+    }
+    private static native byte[] decodeBase64Native(String data);
+}
+
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
new file mode 100644
index 0000000..8f1a756
--- /dev/null
+++ b/core/java/android/os/BatteryManager.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 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;
+
+/**
+ * The BatteryManager class contains strings and constants used for values
+ * in the ACTION_BATTERY_CHANGED Intent.
+ */
+public class BatteryManager {
+
+    // values for "status" field in the ACTION_BATTERY_CHANGED Intent
+    public static final int BATTERY_STATUS_UNKNOWN = 1;
+    public static final int BATTERY_STATUS_CHARGING = 2;
+    public static final int BATTERY_STATUS_DISCHARGING = 3;
+    public static final int BATTERY_STATUS_NOT_CHARGING = 4;
+    public static final int BATTERY_STATUS_FULL = 5;
+
+    // values for "health" field in the ACTION_BATTERY_CHANGED Intent
+    public static final int BATTERY_HEALTH_UNKNOWN = 1;
+    public static final int BATTERY_HEALTH_GOOD = 2;
+    public static final int BATTERY_HEALTH_OVERHEAT = 3;
+    public static final int BATTERY_HEALTH_DEAD = 4;
+    public static final int BATTERY_HEALTH_OVER_VOLTAGE = 5;
+    public static final int BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6;
+
+    // values of the "plugged" field in the ACTION_BATTERY_CHANGED intent.
+    // These must be powers of 2.
+    /** Power source is an AC charger. */
+    public static final int BATTERY_PLUGGED_AC = 1;
+    /** Power source is a USB port. */
+    public static final int BATTERY_PLUGGED_USB = 2;
+}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
new file mode 100644
index 0000000..7590bfe
--- /dev/null
+++ b/core/java/android/os/BatteryStats.java
@@ -0,0 +1,828 @@
+package android.os;
+
+import java.io.PrintWriter;
+import java.util.Formatter;
+import java.util.Map;
+
+import android.util.Log;
+import android.util.Printer;
+import android.util.SparseArray;
+
+/**
+ * A class providing access to battery usage statistics, including information on
+ * wakelocks, processes, packages, and services.  All times are represented in microseconds
+ * except where indicated otherwise.
+ * @hide
+ */
+public abstract class BatteryStats implements Parcelable {
+
+    private static final boolean LOCAL_LOGV = false;
+    
+    /**
+     * A constant indicating a partial wake lock timer.
+     */
+    public static final int WAKE_TYPE_PARTIAL = 0;
+
+    /**
+     * A constant indicating a full wake lock timer.
+     */
+    public static final int WAKE_TYPE_FULL = 1;
+
+    /**
+     * A constant indicating a window wake lock timer.
+     */
+    public static final int WAKE_TYPE_WINDOW = 2;
+    
+    /**
+     * A constant indicating a sensor timer.
+     * 
+     * {@hide}
+     */
+    public static final int SENSOR = 3;
+
+    /**
+     * Include all of the data in the stats, including previously saved data.
+     */
+    public static final int STATS_TOTAL = 0;
+
+    /**
+     * Include only the last run in the stats.
+     */
+    public static final int STATS_LAST = 1;
+
+    /**
+     * Include only the current run in the stats.
+     */
+    public static final int STATS_CURRENT = 2;
+
+    /**
+     * Include only the run since the last time the device was unplugged in the stats.
+     */
+    public static final int STATS_UNPLUGGED = 3;
+    
+    /**
+     * Bump the version on this if the checkin format changes.
+     */
+    private static final int BATTERY_STATS_CHECKIN_VERSION = 1;
+    
+    // TODO: Update this list if you add/change any stats above.
+    private static final String[] STAT_NAMES = { "total", "last", "current", "unplugged" };
+
+    private static final String APK_DATA = "apk";
+    private static final String PROCESS_DATA = "process";
+    private static final String SENSOR_DATA = "sensor";
+    private static final String WAKELOCK_DATA = "wakelock";
+    private static final String NETWORK_DATA = "network";
+    private static final String BATTERY_DATA = "battery";
+    private static final String MISC_DATA = "misc";
+
+    private final StringBuilder mFormatBuilder = new StringBuilder(8);
+    private final Formatter mFormatter = new Formatter(mFormatBuilder);
+
+    /**
+     * State for keeping track of timing information.
+     */
+    public static abstract class Timer {
+
+        /**
+         * Returns the count associated with this Timer for the
+         * selected type of statistics.
+         *
+         * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
+         */
+        public abstract int getCount(int which);
+
+        /**
+         * Returns the total time in microseconds associated with this Timer for the
+         * selected type of statistics.
+         *
+         * @param batteryRealtime system realtime on  battery in microseconds
+         * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
+         * @return a time in microseconds
+         */
+        public abstract long getTotalTime(long batteryRealtime, int which);
+        
+        /**
+         * Temporary for debugging.
+         */
+        public abstract void logState();
+    }
+
+    /**
+     * The statistics associated with a particular uid.
+     */
+    public static abstract class Uid {
+
+        /**
+         * Returns a mapping containing wakelock statistics.
+         *
+         * @return a Map from Strings to Uid.Wakelock objects.
+         */
+        public abstract Map<String, ? extends Wakelock> getWakelockStats();
+
+        /**
+         * The statistics associated with a particular wake lock.
+         */
+        public static abstract class Wakelock {
+            public abstract Timer getWakeTime(int type);
+        }
+
+        /**
+         * Returns a mapping containing sensor statistics.
+         *
+         * @return a Map from Integer sensor ids to Uid.Sensor objects.
+         */
+        public abstract Map<Integer, ? extends Sensor> getSensorStats();
+
+        /**
+         * Returns a mapping containing process statistics.
+         *
+         * @return a Map from Strings to Uid.Proc objects.
+         */
+        public abstract Map<String, ? extends Proc> getProcessStats();
+
+        /**
+         * Returns a mapping containing package statistics.
+         *
+         * @return a Map from Strings to Uid.Pkg objects.
+         */
+        public abstract Map<String, ? extends Pkg> getPackageStats();
+        
+        /**
+         * {@hide}
+         */
+        public abstract int getUid();
+        
+        /**
+         * {@hide}
+         */
+        public abstract long getTcpBytesReceived(int which);
+        
+        /**
+         * {@hide}
+         */
+        public abstract long getTcpBytesSent(int which);
+
+        public static abstract class Sensor {
+            // Magic sensor number for the GPS.
+            public static final int GPS = -10000;
+            
+            public abstract int getHandle();
+            
+            public abstract Timer getSensorTime();
+        }
+
+        /**
+         * The statistics associated with a particular process.
+         */
+        public static abstract class Proc {
+
+            /**
+             * Returns the total time (in 1/100 sec) spent executing in user code.
+             *
+             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+             */
+            public abstract long getUserTime(int which);
+
+            /**
+             * Returns the total time (in 1/100 sec) spent executing in system code.
+             *
+             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+             */
+            public abstract long getSystemTime(int which);
+
+            /**
+             * Returns the number of times the process has been started.
+             *
+             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+             */
+            public abstract int getStarts(int which);
+        }
+
+        /**
+         * The statistics associated with a particular package.
+         */
+        public static abstract class Pkg {
+
+            /**
+             * Returns the number of times this package has done something that could wake up the
+             * device from sleep.
+             *
+             * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+             */
+            public abstract int getWakeups(int which);
+
+            /**
+             * Returns a mapping containing service statistics.
+             */
+            public abstract Map<String, ? extends Serv> getServiceStats();
+
+            /**
+             * The statistics associated with a particular service.
+             */
+            public abstract class Serv {
+
+                /**
+                 * Returns the amount of time spent started.
+                 *
+                 * @param batteryUptime elapsed uptime on battery in microseconds.
+                 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+                 * @return
+                 */
+                public abstract long getStartTime(long batteryUptime, int which);
+
+                /**
+                 * Returns the total number of times startService() has been called.
+                 *
+                 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+                 */
+                public abstract int getStarts(int which);
+
+                /**
+                 * Returns the total number times the service has been launched.
+                 *
+                 * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+                 */
+                public abstract int getLaunches(int which);
+            }
+        }
+    }
+
+    /**
+     * Returns the number of times the device has been started.
+     */
+    public abstract int getStartCount();
+    
+    /**
+     * Returns the time in milliseconds that the screen has been on while the device was
+     * running on battery.
+     * 
+     * {@hide}
+     */
+    public abstract long getScreenOnTime(long batteryRealtime, int which);
+    
+    /**
+     * Returns the time in milliseconds that the phone has been on while the device was
+     * running on battery.
+     * 
+     * {@hide}
+     */
+    public abstract long getPhoneOnTime(long batteryRealtime, int which);
+    
+    /**
+     * Return whether we are currently running on battery.
+     */
+    public abstract boolean getIsOnBattery();
+    
+    /**
+     * Returns a SparseArray containing the statistics for each uid.
+     */
+    public abstract SparseArray<? extends Uid> getUidStats();
+
+    /**
+     * Returns the current battery uptime in microseconds.
+     *
+     * @param curTime the amount of elapsed realtime in microseconds.
+     */
+    public abstract long getBatteryUptime(long curTime);
+
+    /**
+     * Returns the current battery realtime in microseconds.
+     *
+     * @param curTime the amount of elapsed realtime in microseconds.
+     */
+    public abstract long getBatteryRealtime(long curTime);
+
+    /**
+     * Returns the total, last, or current battery uptime in microseconds.
+     *
+     * @param curTime the elapsed realtime in microseconds.
+     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+     */
+    public abstract long computeBatteryUptime(long curTime, int which);
+
+    /**
+     * Returns the total, last, or current battery realtime in microseconds.
+     *
+     * @param curTime the current elapsed realtime in microseconds.
+     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+     */
+    public abstract long computeBatteryRealtime(long curTime, int which);
+
+    /**
+     * Returns the total, last, or current uptime in microseconds.
+     *
+     * @param curTime the current elapsed realtime in microseconds.
+     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+     */
+    public abstract long computeUptime(long curTime, int which);
+
+    /**
+     * Returns the total, last, or current realtime in microseconds.
+     * *
+     * @param curTime the current elapsed realtime in microseconds.
+     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+     */
+    public abstract long computeRealtime(long curTime, int which);
+
+    private final static void formatTime(StringBuilder out, long seconds) {
+        long days = seconds / (60 * 60 * 24);
+        if (days != 0) {
+            out.append(days);
+            out.append("d ");
+        }
+        long used = days * 60 * 60 * 24;
+
+        long hours = (seconds - used) / (60 * 60);
+        if (hours != 0 || used != 0) {
+            out.append(hours);
+            out.append("h ");
+        }
+        used += hours * 60 * 60;
+
+        long mins = (seconds-used) / 60;
+        if (mins != 0 || used != 0) {
+            out.append(mins);
+            out.append("m ");
+        }
+        used += mins * 60;
+
+        if (seconds != 0 || used != 0) {
+            out.append(seconds-used);
+            out.append("s ");
+        }
+    }
+
+    private final static String formatTime(long time) {
+        long sec = time / 100;
+        StringBuilder sb = new StringBuilder();
+        formatTime(sb, sec);
+        sb.append((time - (sec * 100)) * 10);
+        sb.append("ms ");
+        return sb.toString();
+    }
+
+    private final static String formatTimeMs(long time) {
+        long sec = time / 1000;
+        StringBuilder sb = new StringBuilder();
+        formatTime(sb, sec);
+        sb.append(time - (sec * 1000));
+        sb.append("ms ");
+        return sb.toString();
+    }
+
+    private final String formatRatioLocked(long num, long den) {
+        if (den == 0L) {
+            return "---%";
+        }
+        float perc = ((float)num) / ((float)den) * 100;
+        mFormatBuilder.setLength(0);
+        mFormatter.format("%.1f%%", perc);
+        return mFormatBuilder.toString();
+    }
+
+    /**
+     *
+     * @param sb a StringBuilder object.
+     * @param timer a Timer object contining the wakelock times.
+     * @param batteryRealtime the current on-battery time in microseconds.
+     * @param name the name of the wakelock.
+     * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+     * @param linePrefix a String to be prepended to each line of output.
+     * @return the line prefix
+     */
+    private static final String printWakeLock(StringBuilder sb, Timer timer,
+            long batteryRealtime, String name, int which, String linePrefix) {
+        
+        if (timer != null) {
+            // Convert from microseconds to milliseconds with rounding
+            long totalTimeMicros = timer.getTotalTime(batteryRealtime, which);
+            long totalTimeMillis = (totalTimeMicros + 500) / 1000;
+            
+            int count = timer.getCount(which);
+            if (totalTimeMillis != 0) {
+                sb.append(linePrefix);
+                sb.append(formatTimeMs(totalTimeMillis));
+                sb.append(name);
+                sb.append(' ');
+                sb.append('(');
+                sb.append(count);
+                sb.append(" times)");
+                return ", ";
+            }
+        }
+        return linePrefix;
+    }
+    
+    /**
+     * Checkin version of wakelock printer. Prints simple comma-separated list.
+     * 
+     * @param sb a StringBuilder object.
+     * @param timer a Timer object contining the wakelock times.
+     * @param now the current time in microseconds.
+     * @param name the name of the wakelock.
+     * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+     * @param linePrefix a String to be prepended to each line of output.
+     * @return the line prefix
+     */
+    private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
+        String name, int which, String linePrefix) {
+        long totalTimeMicros = 0;
+        int count = 0;
+        if (timer != null) {
+            totalTimeMicros = timer.getTotalTime(now, which);
+            count = timer.getCount(which); 
+        }
+        sb.append(linePrefix);
+        sb.append((totalTimeMicros + 500) / 1000); // microseconds to milliseconds with rounding
+        sb.append(',');
+        sb.append(name);
+        sb.append(',');
+        sb.append(count);
+        return ",";
+    }
+    
+    /**
+     * Dump a comma-separated line of values for terse checkin mode.
+     * 
+     * @param pw the PageWriter to dump log to
+     * @param category category of data (e.g. "total", "last", "unplugged", "current" )
+     * @param type type of data (e.g. "wakelock", "sensor", "process", "apk" ,  "process", "network")
+     * @param args type-dependent data arguments
+     */
+    private static final void dumpLine(PrintWriter pw, int uid, String category, String type, 
+           Object... args ) {
+        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
+        pw.print(uid); pw.print(',');
+        pw.print(category); pw.print(',');
+        pw.print(type); 
+        
+        for (Object arg : args) {  
+            pw.print(','); 
+            pw.print(arg); 
+        }
+        pw.print('\n');
+    }
+    
+    /**
+     * Checkin server version of dump to produce more compact, computer-readable log.
+     * 
+     * NOTE: all times are expressed in 'ms'.
+     * @param fd
+     * @param pw
+     * @param which
+     */
+    private final void dumpCheckinLocked(PrintWriter pw, int which) {
+        final long rawUptime = SystemClock.uptimeMillis() * 1000;
+        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
+        final long batteryUptime = getBatteryUptime(rawUptime);
+        final long batteryRealtime = getBatteryRealtime(rawRealtime);
+        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
+        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
+        final long totalRealtime = computeRealtime(rawRealtime, which);
+        final long totalUptime = computeUptime(rawUptime, which);
+        final long screenOnTime = getScreenOnTime(batteryRealtime, which);
+        final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
+       
+        StringBuilder sb = new StringBuilder(128);
+        
+        String category = STAT_NAMES[which];
+        
+        // Dump "battery" stat
+        dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 
+                which == STATS_TOTAL ? getStartCount() : "N/A",
+                whichBatteryUptime / 1000, whichBatteryRealtime / 1000, 
+                totalUptime / 1000, totalRealtime / 1000); 
+        
+        // Dump misc stats
+        dumpLine(pw, 0 /* uid */, category, MISC_DATA,
+                screenOnTime / 1000, phoneOnTime / 1000);
+        
+        SparseArray<? extends Uid> uidStats = getUidStats();
+        final int NU = uidStats.size();
+        for (int iu = 0; iu < NU; iu++) {
+            final int uid = uidStats.keyAt(iu);
+            Uid u = uidStats.valueAt(iu);
+            // Dump Network stats per uid, if any
+            long rx = u.getTcpBytesReceived(which);
+            long tx = u.getTcpBytesSent(which);
+            if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
+
+            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
+            if (wakelocks.size() > 0) {
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
+                        : wakelocks.entrySet()) {
+                    Uid.Wakelock wl = ent.getValue();
+                    String linePrefix = "";
+                    sb.setLength(0);
+                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
+                            "full", which, linePrefix);
+                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
+                            "partial", which, linePrefix);
+                    linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
+                            "window", which, linePrefix);
+                    
+                    // Only log if we had at lease one wakelock...
+                    if (sb.length() > 0) {
+                       dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
+                    }
+                }
+            }
+                
+            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
+            if (sensors.size() > 0)  {
+                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
+                        : sensors.entrySet()) {
+                    Uid.Sensor se = ent.getValue();
+                    int sensorNumber = ent.getKey();
+                    Timer timer = se.getSensorTime();
+                    if (timer != null) {
+                        // Convert from microseconds to milliseconds with rounding
+                        long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
+                        int count = timer.getCount(which);
+                        if (totalTime != 0) {
+                            dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
+                        }
+                    } 
+                }
+            }
+
+            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
+            if (processStats.size() > 0) {
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
+                        : processStats.entrySet()) {
+                    Uid.Proc ps = ent.getValue();
+    
+                    long userTime = ps.getUserTime(which);
+                    long systemTime = ps.getSystemTime(which);
+                    int starts = ps.getStarts(which);
+    
+                    if (userTime != 0 || systemTime != 0 || starts != 0) {
+                        dumpLine(pw, uid, category, PROCESS_DATA, 
+                                ent.getKey(), // proc
+                                userTime * 10, // cpu time in ms
+                                systemTime * 10, // user time in ms
+                                starts); // process starts
+                    }
+                }
+            }
+
+            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
+            if (packageStats.size() > 0) {
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
+                        : packageStats.entrySet()) {
+              
+                    Uid.Pkg ps = ent.getValue();
+                    int wakeups = ps.getWakeups(which);
+                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
+                    for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
+                            : serviceStats.entrySet()) {
+                        BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
+                        long startTime = ss.getStartTime(batteryUptime, which);
+                        int starts = ss.getStarts(which);
+                        int launches = ss.getLaunches(which);
+                        if (startTime != 0 || starts != 0 || launches != 0) {
+                            dumpLine(pw, uid, category, APK_DATA, 
+                                    wakeups, // wakeup alarms
+                                    ent.getKey(), // Apk
+                                    sent.getKey(), // service
+                                    startTime / 1000, // time spent started, in ms
+                                    starts,
+                                    launches);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private final void dumpLocked(Printer pw, String prefix, int which) {
+        final long rawUptime = SystemClock.uptimeMillis() * 1000;
+        final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
+        final long batteryUptime = getBatteryUptime(rawUptime);
+        final long batteryRealtime = getBatteryUptime(rawRealtime);
+
+        final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
+        final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
+        final long totalRealtime = computeRealtime(rawRealtime, which);
+        final long totalUptime = computeUptime(rawUptime, which);
+        
+        StringBuilder sb = new StringBuilder(128);
+
+        pw.println(prefix
+                + "  Time on battery: " + formatTimeMs(whichBatteryUptime / 1000)
+                + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime)
+                + ") uptime, "
+                + formatTimeMs(whichBatteryRealtime / 1000) + "("
+                + formatRatioLocked(whichBatteryRealtime, totalRealtime)
+                + ") realtime");
+        pw.println(prefix
+                + "  Total: "
+                + formatTimeMs(totalUptime / 1000)
+                + "uptime, "
+                + formatTimeMs(totalRealtime / 1000)
+                + "realtime");
+        
+        long screenOnTime = getScreenOnTime(batteryRealtime, which);
+        long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
+        pw.println(prefix
+                + "  Time with screen on: " + formatTimeMs(screenOnTime / 1000)
+                + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime)
+                + "), time with phone on: " + formatTimeMs(phoneOnTime / 1000)
+                + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime) + ")");
+        
+        pw.println(" ");
+
+        SparseArray<? extends Uid> uidStats = getUidStats();
+        final int NU = uidStats.size();
+        for (int iu=0; iu<NU; iu++) {
+            final int uid = uidStats.keyAt(iu);
+            Uid u = uidStats.valueAt(iu);
+            pw.println(prefix + "  #" + uid + ":");
+            boolean uidActivity = false;
+            
+            long tcpReceived = u.getTcpBytesReceived(which);
+            long tcpSent = u.getTcpBytesSent(which);
+            if (tcpReceived != 0 || tcpSent != 0) {
+                pw.println(prefix + "    Network: " + tcpReceived + " bytes received, "
+                        + tcpSent + " bytes sent");
+            }
+
+            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
+            if (wakelocks.size() > 0) {
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
+                    : wakelocks.entrySet()) {
+                    Uid.Wakelock wl = ent.getValue();
+                    String linePrefix = ": ";
+                    sb.setLength(0);
+                    sb.append(prefix);
+                    sb.append("    Wake lock ");
+                    sb.append(ent.getKey());
+                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
+                            "full", which, linePrefix);
+                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
+                            "partial", which, linePrefix);
+                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
+                            "window", which, linePrefix);
+                    if (!linePrefix.equals(": ")) {
+                        sb.append(" realtime");
+                    } else {
+                        sb.append(": (nothing executed)");
+                    }
+                    pw.println(sb.toString());
+                    uidActivity = true;
+                }
+            }
+
+            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensors = u.getSensorStats();
+            if (sensors.size() > 0) {
+                for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
+                    : sensors.entrySet()) {
+                    Uid.Sensor se = ent.getValue();
+                    int sensorNumber = ent.getKey();
+                    sb.setLength(0);
+                    sb.append(prefix);
+                    sb.append("    Sensor ");
+                    int handle = se.getHandle();
+                    if (handle == Uid.Sensor.GPS) {
+                        sb.append("GPS");
+                    } else {
+                        sb.append(handle);
+                    }
+                    sb.append(": ");
+
+                    Timer timer = se.getSensorTime();
+                    if (timer != null) {
+                        // Convert from microseconds to milliseconds with rounding
+                        long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
+                        int count = timer.getCount(which);
+                        //timer.logState();
+                        if (totalTime != 0) {
+                            sb.append(formatTimeMs(totalTime));
+                            sb.append("realtime (");
+                            sb.append(count);
+                            sb.append(" times)");
+                        } else {
+                            sb.append("(not used)");
+                        }
+                    } else {
+                        sb.append("(not used)");
+                    }
+
+                    pw.println(sb.toString());
+                    uidActivity = true;
+                }
+            }
+
+            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
+            if (processStats.size() > 0) {
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
+                    : processStats.entrySet()) {
+                    Uid.Proc ps = ent.getValue();
+                    long userTime;
+                    long systemTime;
+                    int starts;
+
+                    userTime = ps.getUserTime(which);
+                    systemTime = ps.getSystemTime(which);
+                    starts = ps.getStarts(which);
+
+                    if (userTime != 0 || systemTime != 0 || starts != 0) {
+                        pw.println(prefix + "    Proc " + ent.getKey() + ":");
+                        pw.println(prefix + "      CPU: " + formatTime(userTime) + "user + "
+                                + formatTime(systemTime) + "kernel");
+                        pw.println(prefix + "      " + starts + " process starts");
+                        uidActivity = true;
+                    }
+                }
+            }
+
+            Map<String, ? extends BatteryStats.Uid.Pkg> packageStats = u.getPackageStats();
+            if (packageStats.size() > 0) {
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg> ent
+                    : packageStats.entrySet()) {
+                    pw.println(prefix + "    Apk " + ent.getKey() + ":");
+                    boolean apkActivity = false;
+                    Uid.Pkg ps = ent.getValue();
+                    int wakeups = ps.getWakeups(which);
+                    if (wakeups != 0) {
+                        pw.println(prefix + "      " + wakeups + " wakeup alarms");
+                        apkActivity = true;
+                    }
+                    Map<String, ? extends  Uid.Pkg.Serv> serviceStats = ps.getServiceStats();
+                    if (serviceStats.size() > 0) {
+                        for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
+                                : serviceStats.entrySet()) {
+                            BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
+                            long startTime = ss.getStartTime(batteryUptime, which);
+                            int starts = ss.getStarts(which);
+                            int launches = ss.getLaunches(which);
+                            if (startTime != 0 || starts != 0 || launches != 0) {
+                                pw.println(prefix + "      Service " + sent.getKey() + ":");
+                                pw.println(prefix + "        Created for: "
+                                        + formatTimeMs(startTime / 1000)
+                                        + " uptime");
+                                pw.println(prefix + "        Starts: " + starts
+                                        + ", launches: " + launches);
+                                apkActivity = true;
+                            }
+                        }
+                    }
+                    if (!apkActivity) {
+                        pw.println(prefix + "      (nothing executed)");
+                    }
+                    uidActivity = true;
+                }
+            }
+            if (!uidActivity) {
+                pw.println(prefix + "    (nothing executed)");
+            }
+        }
+    }
+
+    /**
+     * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
+     *
+     * @param pw a Printer to receive the dump output.
+     */
+    @SuppressWarnings("unused")
+    public void dumpLocked(Printer pw) {
+        pw.println("Total Statistics (Current and Historic):");
+        pw.println("  System starts: " + getStartCount()
+                + ", currently on battery: " + getIsOnBattery());
+        dumpLocked(pw, "", STATS_TOTAL);
+        pw.println("");
+        pw.println("Last Run Statistics (Previous run of system):");
+        dumpLocked(pw, "", STATS_LAST);
+        pw.println("");
+        pw.println("Current Battery Statistics (Currently running system):");
+        dumpLocked(pw, "", STATS_CURRENT);
+        pw.println("");
+        pw.println("Unplugged Statistics (Since last unplugged from power):");
+        dumpLocked(pw, "", STATS_UNPLUGGED);
+    }
+    
+    @SuppressWarnings("unused")
+    public void dumpCheckinLocked(PrintWriter pw, String[] args) {
+        boolean isUnpluggedOnly = false;
+        
+        for (String arg : args) {
+            if ("-u".equals(arg)) {
+                if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
+                isUnpluggedOnly = true;
+            }
+        }
+        
+        if (isUnpluggedOnly) {
+            dumpCheckinLocked(pw, STATS_UNPLUGGED);
+        }
+        else {
+            dumpCheckinLocked(pw, STATS_TOTAL);
+            dumpCheckinLocked(pw, STATS_LAST);
+            dumpCheckinLocked(pw, STATS_UNPLUGGED);
+            dumpCheckinLocked(pw, STATS_CURRENT);
+        }
+    }
+    
+}
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
new file mode 100644
index 0000000..df10c6a
--- /dev/null
+++ b/core/java/android/os/Binder.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2006 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.Config;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Modifier;
+
+/**
+ * Base class for a remotable object, the core part of a lightweight
+ * remote procedure call mechanism defined by {@link IBinder}.
+ * This class is an implementation of IBinder that provides
+ * the standard support creating a local implementation of such an object.
+ * 
+ * <p>Most developers will not implement this class directly, instead using the
+ * <a href="{@docRoot}guide/developing/tools/aidl.html">aidl</a> tool to describe the desired
+ * interface, having it generate the appropriate Binder subclass.  You can,
+ * however, derive directly from Binder to implement your own custom RPC
+ * protocol or simply instantiate a raw Binder object directly to use as a
+ * token that can be shared across processes.
+ * 
+ * @see IBinder
+ */
+public class Binder implements IBinder {
+    /*
+     * Set this flag to true to detect anonymous, local or member classes
+     * that extend this Binder class and that are not static. These kind
+     * of classes can potentially create leaks.
+     */
+    private static final boolean FIND_POTENTIAL_LEAKS = false;
+    private static final String TAG = "Binder";
+
+    private int mObject;
+    private IInterface mOwner;
+    private String mDescriptor;
+    
+    /**
+     * Return the ID of the process that sent you the current transaction
+     * that is being processed.  This pid can be used with higher-level
+     * system services to determine its identity and check permissions.
+     * If the current thread is not currently executing an incoming transaction,
+     * then its own pid is returned.
+     */
+    public static final native int getCallingPid();
+    
+    /**
+     * Return the ID of the user assigned to the process that sent you the
+     * current transaction that is being processed.  This uid can be used with
+     * higher-level system services to determine its identity and check
+     * permissions.  If the current thread is not currently executing an
+     * incoming transaction, then its own uid is returned.
+     */
+    public static final native int getCallingUid();
+    
+    /**
+     * Reset the identity of the incoming IPC to the local process.  This can
+     * be useful if, while handling an incoming call, you will be calling
+     * on interfaces of other objects that may be local to your process and
+     * need to do permission checks on the calls coming into them (so they
+     * will check the permission of your own local process, and not whatever
+     * process originally called you).
+     * 
+     * @return Returns an opaque token that can be used to restore the
+     * original calling identity by passing it to
+     * {@link #restoreCallingIdentity(long)}.
+     * 
+     * @see #getCallingPid()
+     * @see #getCallingUid()
+     * @see #restoreCallingIdentity(long)
+     */
+    public static final native long clearCallingIdentity();
+    
+    /**
+     * Restore the identity of the incoming IPC back to a previously identity
+     * that was returned by {@link #clearCallingIdentity}.
+     * 
+     * @param token The opaque token that was previously returned by
+     * {@link #clearCallingIdentity}.
+     * 
+     * @see #clearCallingIdentity
+     */
+    public static final native void restoreCallingIdentity(long token);
+    
+    /**
+     * Flush any Binder commands pending in the current thread to the kernel
+     * driver.  This can be
+     * useful to call before performing an operation that may block for a long
+     * time, to ensure that any pending object references have been released
+     * in order to prevent the process from holding on to objects longer than
+     * it needs to.
+     */
+    public static final native void flushPendingCommands();
+    
+    /**
+     * Add the calling thread to the IPC thread pool.  This function does
+     * not return until the current process is exiting.
+     */
+    public static final native void joinThreadPool();
+    
+    /**
+     * Default constructor initializes the object.
+     */
+    public Binder() {
+        init();
+
+        if (FIND_POTENTIAL_LEAKS) {
+            final Class<? extends Binder> klass = getClass();
+            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
+                    (klass.getModifiers() & Modifier.STATIC) == 0) {
+                Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
+                    klass.getCanonicalName());
+            }
+        }
+    }
+    
+    /**
+     * Convenience method for associating a specific interface with the Binder.
+     * After calling, queryLocalInterface() will be implemented for you
+     * to return the given owner IInterface when the corresponding
+     * descriptor is requested.
+     */
+    public void attachInterface(IInterface owner, String descriptor) {
+        mOwner = owner;
+        mDescriptor = descriptor;
+    }
+    
+    /**
+     * Default implementation returns an empty interface name.
+     */
+    public String getInterfaceDescriptor() {
+        return mDescriptor;
+    }
+
+    /**
+     * Default implementation always returns true -- if you got here,
+     * the object is alive.
+     */
+    public boolean pingBinder() {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Note that if you're calling on a local binder, this always returns true
+     * because your process is alive if you're calling it.
+     */
+    public boolean isBinderAlive() {
+        return true;
+    }
+    
+    /**
+     * Use information supplied to attachInterface() to return the
+     * associated IInterface if it matches the requested
+     * descriptor.
+     */
+    public IInterface queryLocalInterface(String descriptor) {
+        if (mDescriptor.equals(descriptor)) {
+            return mOwner;
+        }
+        return null;
+    }
+    
+    /**
+     * Default implementation is a stub that returns false.  You will want
+     * to override this to do the appropriate unmarshalling of transactions.
+     *
+     * <p>If you want to call this, call transact().
+     */
+    protected boolean onTransact(int code, Parcel data, Parcel reply,
+            int flags) throws RemoteException {
+        if (code == INTERFACE_TRANSACTION) {
+            reply.writeString(getInterfaceDescriptor());
+            return true;
+        } else if (code == DUMP_TRANSACTION) {
+            ParcelFileDescriptor fd = data.readFileDescriptor();
+            String[] args = data.readStringArray();
+            if (fd != null) {
+                try {
+                    dump(fd.getFileDescriptor(), args);
+                } finally {
+                    try {
+                        fd.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Implemented to call the more convenient version
+     * {@link #dump(FileDescriptor, PrintWriter, String[])}.
+     */
+    public void dump(FileDescriptor fd, String[] args) {
+        FileOutputStream fout = new FileOutputStream(fd);
+        PrintWriter pw = new PrintWriter(fout);
+        try {
+            dump(fd, pw, args);
+        } finally {
+            pw.flush();
+        }
+    }
+    
+    /**
+     * Print the object's state into the given stream.
+     * 
+     * @param fd The raw file descriptor that the dump is being sent to.
+     * @param fout The file to which you should dump your state.  This will be
+     * closed for you after you return.
+     * @param args additional arguments to the dump request.
+     */
+    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+    }
+
+    /**
+     * Default implementation rewinds the parcels and calls onTransact.  On
+     * the remote side, transact calls into the binder to do the IPC.
+     */
+    public final boolean transact(int code, Parcel data, Parcel reply,
+            int flags) throws RemoteException {
+        if (Config.LOGV) Log.v("Binder", "Transact: " + code + " to " + this);
+        if (data != null) {
+            data.setDataPosition(0);
+        }
+        boolean r = onTransact(code, data, reply, flags);
+        if (reply != null) {
+            reply.setDataPosition(0);
+        }
+        return r;
+    }
+    
+    /**
+     * Local implementation is a no-op.
+     */
+    public void linkToDeath(DeathRecipient recipient, int flags) {
+    }
+
+    /**
+     * Local implementation is a no-op.
+     */
+    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
+        return true;
+    }
+    
+    protected void finalize() throws Throwable {
+        try {
+            destroy();
+        } finally {
+            super.finalize();
+        }
+    }
+    
+    private native final void init();
+    private native final void destroy();
+    private boolean execTransact(int code, int dataObj, int replyObj,
+            int flags) {
+        Parcel data = Parcel.obtain(dataObj);
+        Parcel reply = Parcel.obtain(replyObj);
+        // theoretically, we should call transact, which will call onTransact,
+        // but all that does is rewind it, and we just got these from an IPC,
+        // so we'll just call it directly.
+        boolean res;
+        try {
+            res = onTransact(code, data, reply, flags);
+        } catch (RemoteException e) {
+            reply.writeException(e);
+            res = true;
+        } catch (RuntimeException e) {
+            reply.writeException(e);
+            res = true;
+        }
+        reply.recycle();
+        data.recycle();
+        return res;
+    }
+}
+
+final class BinderProxy implements IBinder {
+    public native boolean pingBinder();
+    public native boolean isBinderAlive();
+    
+    public IInterface queryLocalInterface(String descriptor) {
+        return null;
+    }
+    
+    public native String getInterfaceDescriptor() throws RemoteException;
+    public native boolean transact(int code, Parcel data, Parcel reply,
+            int flags) throws RemoteException;
+    public native void linkToDeath(DeathRecipient recipient, int flags)
+            throws RemoteException;
+    public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
+
+    public void dump(FileDescriptor fd, String[] args) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeFileDescriptor(fd);
+        data.writeStringArray(args);
+        try {
+            transact(DUMP_TRANSACTION, data, null, 0);
+        } finally {
+            data.recycle();
+        }
+    }
+    
+    BinderProxy() {
+        mSelf = new WeakReference(this);
+    }
+    
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            destroy();
+        } finally {
+            super.finalize();
+        }
+    }
+    
+    private native final void destroy();
+    
+    private static final void sendDeathNotice(DeathRecipient recipient) {
+        if (Config.LOGV) Log.v("JavaBinder", "sendDeathNotice to " + recipient);
+        try {
+            recipient.binderDied();
+        }
+        catch (RuntimeException exc) {
+            Log.w("BinderNative", "Uncaught exception from death notification",
+                    exc);
+        }
+    }
+    
+    final private WeakReference mSelf;
+    private int mObject;
+}
diff --git a/core/java/android/os/Broadcaster.java b/core/java/android/os/Broadcaster.java
new file mode 100644
index 0000000..96dc61a
--- /dev/null
+++ b/core/java/android/os/Broadcaster.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2006 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;
+
+/** @hide */
+public class Broadcaster
+{
+    public Broadcaster()
+    {
+    }
+
+    /**
+     *  Sign up for notifications about something.
+     *
+     *  When this broadcaster pushes a message with senderWhat in the what field,
+     *  target will be sent a copy of that message with targetWhat in the what field.
+     */
+    public void request(int senderWhat, Handler target, int targetWhat)
+    {
+        synchronized (this) {
+            Registration r = null;
+            if (mReg == null) {
+                r = new Registration();
+                r.senderWhat = senderWhat;
+                r.targets = new Handler[1];
+                r.targetWhats = new int[1];
+                r.targets[0] = target;
+                r.targetWhats[0] = targetWhat;
+                mReg = r;
+                r.next = r;
+                r.prev = r;
+            } else {
+                // find its place in the map
+                Registration start = mReg;
+                r = start;
+                do {
+                    if (r.senderWhat >= senderWhat) {
+                        break;
+                    }
+                    r = r.next;
+                } while (r != start);
+                int n;
+                if (r.senderWhat != senderWhat) {
+                    // we didn't find a senderWhat match, but r is right
+                    // after where it goes
+                    Registration reg = new Registration();
+                    reg.senderWhat = senderWhat;
+                    reg.targets = new Handler[1];
+                    reg.targetWhats = new int[1];
+                    reg.next = r;
+                    reg.prev = r.prev;
+                    r.prev.next = reg;
+                    r.prev = reg;
+
+                    if (r == mReg && r.senderWhat > reg.senderWhat) {
+                        mReg = reg;
+                    }
+                    
+                    r = reg;
+                    n = 0;
+                } else {
+                    n = r.targets.length;
+                    Handler[] oldTargets = r.targets;
+                    int[] oldWhats = r.targetWhats;
+                    // check for duplicates, and don't do it if we are dup.
+                    for (int i=0; i<n; i++) {
+                        if (oldTargets[i] == target && oldWhats[i] == targetWhat) {
+                            return;
+                        }
+                    }
+                    r.targets = new Handler[n+1];
+                    System.arraycopy(oldTargets, 0, r.targets, 0, n);
+                    r.targetWhats = new int[n+1];
+                    System.arraycopy(oldWhats, 0, r.targetWhats, 0, n);
+                }
+                r.targets[n] = target;
+                r.targetWhats[n] = targetWhat;
+            }
+        }
+    }
+    
+    /**
+     * Unregister for notifications for this senderWhat/target/targetWhat tuple.
+     */
+    public void cancelRequest(int senderWhat, Handler target, int targetWhat)
+    {
+        synchronized (this) {
+            Registration start = mReg;
+            Registration r = start;
+            
+            if (r == null) {
+                return;
+            }
+            
+            do {
+                if (r.senderWhat >= senderWhat) {
+                    break;
+                }
+                r = r.next;
+            } while (r != start);
+            
+            if (r.senderWhat == senderWhat) {
+                Handler[] targets = r.targets;
+                int[] whats = r.targetWhats;
+                int oldLen = targets.length;
+                for (int i=0; i<oldLen; i++) {
+                    if (targets[i] == target && whats[i] == targetWhat) {
+                        r.targets = new Handler[oldLen-1];
+                        r.targetWhats = new int[oldLen-1];
+                        if (i > 0) {
+                            System.arraycopy(targets, 0, r.targets, 0, i);
+                            System.arraycopy(whats, 0, r.targetWhats, 0, i);
+                        }
+
+                        int remainingLen = oldLen-i-1;
+                        if (remainingLen != 0) {
+                            System.arraycopy(targets, i+1, r.targets, i,
+                                    remainingLen);
+                            System.arraycopy(whats, i+1, r.targetWhats, i,
+                                    remainingLen);
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * For debugging purposes, print the registrations to System.out
+     */
+    public void dumpRegistrations()
+    {
+        synchronized (this) {
+            Registration start = mReg;
+            System.out.println("Broadcaster " + this + " {");
+            if (start != null) {
+                Registration r = start;
+                do {
+                    System.out.println("    senderWhat=" + r.senderWhat);
+                    int n = r.targets.length;
+                    for (int i=0; i<n; i++) {
+                        System.out.println("        [" + r.targetWhats[i]
+                                        + "] " + r.targets[i]);
+                    }
+                    r = r.next;
+                } while (r != start);
+            }
+            System.out.println("}");
+        }
+    }
+
+    /**
+     * Send out msg.  Anyone who has registered via the request() method will be
+     * sent the message.
+     */
+    public void broadcast(Message msg)
+    {
+        synchronized (this) {
+        	if (mReg == null) {
+        		return;
+        	}
+        	
+            int senderWhat = msg.what;
+            Registration start = mReg;
+            Registration r = start;
+            do {
+                if (r.senderWhat >= senderWhat) {
+                    break;
+                }
+                r = r.next;
+            } while (r != start);
+            if (r.senderWhat == senderWhat) {
+                Handler[] targets = r.targets;
+                int[] whats = r.targetWhats;
+                int n = targets.length;
+                for (int i=0; i<n; i++) {
+                    Handler target = targets[i];
+                    Message m = Message.obtain();
+                    m.copyFrom(msg);
+                    m.what = whats[i];
+                    target.sendMessage(m);
+                }
+            }
+        }
+    }
+
+    private class Registration
+    {
+        Registration next;
+        Registration prev;
+
+        int senderWhat;
+        Handler[] targets;
+        int[] targetWhats;
+    }
+    private Registration mReg;
+}
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
new file mode 100644
index 0000000..467c17f
--- /dev/null
+++ b/core/java/android/os/Build.java
@@ -0,0 +1,92 @@
+/*
+ * 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;
+
+/**
+ * Information about the current build, extracted from system properties.
+ */
+public class Build {
+    /** Value used for when a build property is unknown. */
+    private static final String UNKNOWN = "unknown";
+
+    /** Either a changelist number, or a label like "M4-rc20". */
+    public static final String ID = getString("ro.build.id");
+
+    /** A build ID string meant for displaying to the user */
+    public static final String DISPLAY = getString("ro.build.display.id");
+
+    /** The name of the overall product. */
+    public static final String PRODUCT = getString("ro.product.name");
+
+    /** The name of the industrial design. */
+    public static final String DEVICE = getString("ro.product.device");
+
+    /** The name of the underlying board, like "goldfish". */
+    public static final String BOARD = getString("ro.product.board");
+
+    /** The brand (e.g., carrier) the software is customized for, if any. */
+    public static final String BRAND = getString("ro.product.brand");
+
+    /** The end-user-visible name for the end product. */
+    public static final String MODEL = getString("ro.product.model");
+
+    /** Various version strings. */
+    public static class VERSION {
+        /**
+         * The internal value used by the underlying source control to
+         * represent this build.  E.g., a perforce changelist number
+         * or a git hash.
+         */
+        public static final String INCREMENTAL = getString("ro.build.version.incremental");
+
+        /**
+         * The user-visible version string.  E.g., "1.0" or "3.4b5".
+         */
+        public static final String RELEASE = getString("ro.build.version.release");
+
+        /**
+         * The user-visible SDK version of the framework. It is an integer starting at 1.
+         */
+        public static final String SDK = getString("ro.build.version.sdk");
+    }
+
+    /** The type of build, like "user" or "eng". */
+    public static final String TYPE = getString("ro.build.type");
+
+    /** Comma-separated tags describing the build, like "unsigned,debug". */
+    public static final String TAGS = getString("ro.build.tags");
+
+    /** A string that uniquely identifies this build.  Do not attempt to parse this value. */
+    public static final String FINGERPRINT = getString("ro.build.fingerprint");
+
+    // The following properties only make sense for internal engineering builds.
+    public static final long TIME = getLong("ro.build.date.utc") * 1000;
+    public static final String USER = getString("ro.build.user");
+    public static final String HOST = getString("ro.build.host");
+
+    private static String getString(String property) {
+        return SystemProperties.get(property, UNKNOWN);
+    }
+
+    private static long getLong(String property) {
+        try {
+            return Long.parseLong(SystemProperties.get(property));
+        } catch (NumberFormatException e) {
+            return -1;
+        }
+    }
+}
diff --git a/core/java/android/os/Bundle.aidl b/core/java/android/os/Bundle.aidl
new file mode 100644
index 0000000..b9e1224
--- /dev/null
+++ b/core/java/android/os/Bundle.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/os/Bundle.aidl
+**
+** Copyright 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;
+
+parcelable Bundle;
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
new file mode 100644
index 0000000..b669fa2
--- /dev/null
+++ b/core/java/android/os/Bundle.java
@@ -0,0 +1,1452 @@
+/*
+ * 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 android.util.SparseArray;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A mapping from String values to various Parcelable types.
+ *
+ */
+public final class Bundle implements Parcelable, Cloneable {
+    private static final String LOG_TAG = "Bundle";
+    public static final Bundle EMPTY;
+
+    static {
+        EMPTY = new Bundle();
+        EMPTY.mMap = Collections.unmodifiableMap(new HashMap<String, Object>());
+    }
+
+    // Invariant - exactly one of mMap / mParcelledData will be null
+    // (except inside a call to unparcel)
+
+    /* package */ Map<String, Object> mMap = null;
+
+    /*
+     * If mParcelledData is non-null, then mMap will be null and the
+     * data are stored as a Parcel containing a Bundle.  When the data
+     * are unparcelled, mParcelledData willbe set to null.
+     */
+    /* package */ Parcel mParcelledData = null;
+
+    private boolean mHasFds = false;
+    private boolean mFdsKnown = true;
+
+    /**
+     * The ClassLoader used when unparcelling data from mParcelledData.
+     */
+    private ClassLoader mClassLoader;
+
+    /**
+     * Constructs a new, empty Bundle.
+     */
+    public Bundle() {
+        mMap = new HashMap<String, Object>();
+        mClassLoader = getClass().getClassLoader();
+    }
+
+    /**
+     * Constructs a Bundle whose data is stored as a Parcel.  The data
+     * will be unparcelled on first contact, using the assigned ClassLoader.
+     *
+     * @param parcelledData a Parcel containing a Bundle
+     */
+    Bundle(Parcel parcelledData) {
+        readFromParcel(parcelledData);
+    }
+
+    /**
+     * Constructs a new, empty Bundle that uses a specific ClassLoader for
+     * instantiating Parcelable and Serializable objects.
+     *
+     * @param loader An explicit ClassLoader to use when instantiating objects
+     * inside of the Bundle.
+     */
+    public Bundle(ClassLoader loader) {
+        mMap = new HashMap<String, Object>();
+        mClassLoader = loader;
+    }
+
+    /**
+     * Constructs a new, empty Bundle sized to hold the given number of
+     * elements. The Bundle will grow as needed.
+     *
+     * @param capacity the initial capacity of the Bundle
+     */
+    public Bundle(int capacity) {
+        mMap = new HashMap<String, Object>(capacity);
+        mClassLoader = getClass().getClassLoader();
+    }
+
+    /**
+     * Constructs a Bundle containing a copy of the mappings from the given
+     * Bundle.
+     *
+     * @param b a Bundle to be copied.
+     */
+    public Bundle(Bundle b) {
+        if (b.mParcelledData != null) {
+            mParcelledData = Parcel.obtain();
+            mParcelledData.appendFrom(b.mParcelledData, 0, b.mParcelledData.dataSize());
+            mParcelledData.setDataPosition(0);
+        } else {
+            mParcelledData = null;
+        }
+
+        if (b.mMap != null) {
+            mMap = new HashMap<String, Object>(b.mMap);
+        } else {
+            mMap = null;
+        }
+
+        mHasFds = b.mHasFds;
+        mFdsKnown = b.mFdsKnown;
+        mClassLoader = b.mClassLoader;
+    }
+
+    /**
+     * Changes the ClassLoader this Bundle uses when instantiating objects.
+     *
+     * @param loader An explicit ClassLoader to use when instantiating objects
+     * inside of the Bundle.
+     */
+    public void setClassLoader(ClassLoader loader) {
+        mClassLoader = loader;
+    }
+
+    /**
+     * Clones the current Bundle. The internal map is cloned, but the keys and
+     * values to which it refers are copied by reference.
+     */
+    @Override
+    public Object clone() {
+        return new Bundle(this);
+    }
+
+    /**
+     * If the underlying data are stored as a Parcel, unparcel them
+     * using the currently assigned class loader.
+     */
+    /* package */ synchronized void unparcel() {
+        if (mParcelledData == null) {
+            return;
+        }
+
+        mParcelledData.setDataPosition(0);
+        Bundle b = mParcelledData.readBundleUnpacked(mClassLoader);
+        mMap = b.mMap;
+
+        mHasFds = mParcelledData.hasFileDescriptors();
+        mFdsKnown = true;
+        
+        mParcelledData.recycle();
+        mParcelledData = null;
+    }
+
+    /**
+     * Returns the number of mappings contained in this Bundle.
+     *
+     * @return the number of mappings as an int.
+     */
+    public int size() {
+        unparcel();
+        return mMap.size();
+    }
+
+    /**
+     * Returns true if the mapping of this Bundle is empty, false otherwise.
+     */
+    public boolean isEmpty() {
+        unparcel();
+        return mMap.isEmpty();
+    }
+
+    /**
+     * Removes all elements from the mapping of this Bundle.
+     */
+    public void clear() {
+        unparcel();
+        mMap.clear();
+        mHasFds = false;
+        mFdsKnown = true;
+    }
+
+    /**
+     * Returns true if the given key is contained in the mapping
+     * of this Bundle.
+     *
+     * @param key a String key
+     * @return true if the key is part of the mapping, false otherwise
+     */
+    public boolean containsKey(String key) {
+        unparcel();
+        return mMap.containsKey(key);
+    }
+
+    /**
+     * Returns the entry with the given key as an object.
+     *
+     * @param key a String key
+     * @return an Object, or null
+     */
+    public Object get(String key) {
+        unparcel();
+        return mMap.get(key);
+    }
+
+    /**
+     * Removes any entry with the given key from the mapping of this Bundle.
+     *
+     * @param key a String key
+     */
+    public void remove(String key) {
+        unparcel();
+        mMap.remove(key);
+    }
+
+    /**
+     * Inserts all mappings from the given Bundle into this Bundle.
+     *
+     * @param map a Bundle
+     */
+    public void putAll(Bundle map) {
+        unparcel();
+        map.unparcel();
+        mMap.putAll(map.mMap);
+
+        // fd state is now known if and only if both bundles already knew
+        mHasFds |= map.mHasFds;
+        mFdsKnown = mFdsKnown && map.mFdsKnown;
+    }
+
+    /**
+     * Returns a Set containing the Strings used as keys in this Bundle.
+     *
+     * @return a Set of String keys
+     */
+    public Set<String> keySet() {
+        unparcel();
+        return mMap.keySet();
+    }
+
+    /**
+     * Reports whether the bundle contains any parcelled file descriptors.
+     */
+    public boolean hasFileDescriptors() {
+        if (!mFdsKnown) {
+            boolean fdFound = false;    // keep going until we find one or run out of data
+            
+            if (mParcelledData != null) {
+                if (mParcelledData.hasFileDescriptors()) {
+                    fdFound = true;
+                }
+            } else {
+                // It's been unparcelled, so we need to walk the map
+                Iterator<Map.Entry<String, Object>> iter = mMap.entrySet().iterator();
+                while (!fdFound && iter.hasNext()) {
+                    Object obj = iter.next().getValue();
+                    if (obj instanceof Parcelable) {
+                        if ((((Parcelable)obj).describeContents()
+                                & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
+                            fdFound = true;
+                            break;
+                        }
+                    } else if (obj instanceof Parcelable[]) {
+                        Parcelable[] array = (Parcelable[]) obj;
+                        for (int n = array.length - 1; n >= 0; n--) {
+                            if ((array[n].describeContents()
+                                    & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
+                                fdFound = true;
+                                break;
+                            }
+                        }
+                    } else if (obj instanceof SparseArray) {
+                        SparseArray<? extends Parcelable> array =
+                                (SparseArray<? extends Parcelable>) obj;
+                        for (int n = array.size() - 1; n >= 0; n--) {
+                            if ((array.get(n).describeContents()
+                                    & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
+                                fdFound = true;
+                                break;
+                            }
+                        }
+                    } else if (obj instanceof ArrayList) {
+                        ArrayList array = (ArrayList) obj;
+                        // an ArrayList here might contain either Strings or
+                        // Parcelables; only look inside for Parcelables
+                        if ((array.size() > 0)
+                                && (array.get(0) instanceof Parcelable)) {
+                            for (int n = array.size() - 1; n >= 0; n--) {
+                                Parcelable p = (Parcelable) array.get(n);
+                                if (p != null && ((p.describeContents()
+                                        & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
+                                    fdFound = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            mHasFds = fdFound;
+            mFdsKnown = true;
+        }
+        return mHasFds;
+    }
+    
+    /**
+     * Inserts a Boolean value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a Boolean, or null
+     */
+    public void putBoolean(String key, boolean value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a byte value into the mapping of this Bundle, replacing
+     * any existing value for the given key.
+     *
+     * @param key a String, or null
+     * @param value a byte
+     */
+    public void putByte(String key, byte value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a char value into the mapping of this Bundle, replacing
+     * any existing value for the given key.
+     *
+     * @param key a String, or null
+     * @param value a char, or null
+     */
+    public void putChar(String key, char value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a short value into the mapping of this Bundle, replacing
+     * any existing value for the given key.
+     *
+     * @param key a String, or null
+     * @param value a short
+     */
+    public void putShort(String key, short value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts an int value into the mapping of this Bundle, replacing
+     * any existing value for the given key.
+     *
+     * @param key a String, or null
+     * @param value an int, or null
+     */
+    public void putInt(String key, int value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a long value into the mapping of this Bundle, replacing
+     * any existing value for the given key.
+     *
+     * @param key a String, or null
+     * @param value a long
+     */
+    public void putLong(String key, long value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a float value into the mapping of this Bundle, replacing
+     * any existing value for the given key.
+     *
+     * @param key a String, or null
+     * @param value a float
+     */
+    public void putFloat(String key, float value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a double value into the mapping of this Bundle, replacing
+     * any existing value for the given key.
+     *
+     * @param key a String, or null
+     * @param value a double
+     */
+    public void putDouble(String key, double value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a String value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a String, or null
+     */
+    public void putString(String key, String value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a CharSequence value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a CharSequence, or null
+     */
+    public void putCharSequence(String key, CharSequence value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a Parcelable value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a Parcelable object, or null
+     */
+    public void putParcelable(String key, Parcelable value) {
+        unparcel();
+        mMap.put(key, value);
+        mFdsKnown = false;
+    }
+
+    /**
+     * Inserts an array of Parcelable values into the mapping of this Bundle,
+     * replacing any existing value for the given key.  Either key or value may
+     * be null.
+     *
+     * @param key a String, or null
+     * @param value an array of Parcelable objects, or null
+     */
+    public void putParcelableArray(String key, Parcelable[] value) {
+        unparcel();
+        mMap.put(key, value);
+        mFdsKnown = false;
+    }
+
+    /**
+     * Inserts a List of Parcelable values into the mapping of this Bundle,
+     * replacing any existing value for the given key.  Either key or value may
+     * be null.
+     *
+     * @param key a String, or null
+     * @param value an ArrayList of Parcelable objects, or null
+     */
+    public void putParcelableArrayList(String key,
+        ArrayList<? extends Parcelable> value) {
+        unparcel();
+        mMap.put(key, value);
+        mFdsKnown = false;
+    }
+
+    /**
+     * Inserts a SparceArray of Parcelable values into the mapping of this
+     * Bundle, replacing any existing value for the given key.  Either key
+     * or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a SparseArray of Parcelable objects, or null
+     */
+    public void putSparseParcelableArray(String key,
+            SparseArray<? extends Parcelable> value) {
+        unparcel();
+        mMap.put(key, value);
+        mFdsKnown = false;
+    }
+
+    /**
+     * Inserts an ArrayList<Integer> value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value an ArrayList<Integer> object, or null
+     */
+    public void putIntegerArrayList(String key, ArrayList<Integer> value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts an ArrayList<String> value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value an ArrayList<String> object, or null
+     */
+    public void putStringArrayList(String key, ArrayList<String> value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a Serializable value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a Serializable object, or null
+     */
+    public void putSerializable(String key, Serializable value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a boolean array value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a boolean array object, or null
+     */
+    public void putBooleanArray(String key, boolean[] value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a byte array value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a byte array object, or null
+     */
+    public void putByteArray(String key, byte[] value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a short array value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a short array object, or null
+     */
+    public void putShortArray(String key, short[] value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a char array value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a char array object, or null
+     */
+    public void putCharArray(String key, char[] value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts an int array value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value an int array object, or null
+     */
+    public void putIntArray(String key, int[] value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a long array value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a long array object, or null
+     */
+    public void putLongArray(String key, long[] value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a float array value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a float array object, or null
+     */
+    public void putFloatArray(String key, float[] value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a double array value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a double array object, or null
+     */
+    public void putDoubleArray(String key, double[] value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a String array value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a String array object, or null
+     */
+    public void putStringArray(String key, String[] value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts a Bundle value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value a Bundle object, or null
+     */
+    public void putBundle(String key, Bundle value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Inserts an IBinder value into the mapping of this Bundle, replacing
+     * any existing value for the given key.  Either key or value may be null.
+     *
+     * @param key a String, or null
+     * @param value an IBinder object, or null
+     *
+     * @deprecated
+     * @hide
+     */
+    @Deprecated
+    public void putIBinder(String key, IBinder value) {
+        unparcel();
+        mMap.put(key, value);
+    }
+
+    /**
+     * Returns the value associated with the given key, or false if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a boolean value
+     */
+    public boolean getBoolean(String key) {
+        unparcel();
+        return getBoolean(key, false);
+    }
+
+    // Log a message if the value was non-null but not of the expected type
+    private void typeWarning(String key, Object value, String className,
+        Object defaultValue, ClassCastException e) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Key ");
+        sb.append(key);
+        sb.append(" expected ");
+        sb.append(className);
+        sb.append(" but value was a ");
+        sb.append(value.getClass().getName());
+        sb.append(".  The default value ");
+        sb.append(defaultValue);
+        sb.append(" was returned.");
+        Log.w(LOG_TAG, sb.toString());
+        Log.w(LOG_TAG, "Attempt to cast generated internal exception:", e);
+    }
+
+    private void typeWarning(String key, Object value, String className,
+        ClassCastException e) {
+        typeWarning(key, value, className, "<null>", e);
+    }
+
+    /**
+     * Returns the value associated with the given key, or defaultValue if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a boolean value
+     */
+    public boolean getBoolean(String key, boolean defaultValue) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return defaultValue;
+        }
+        try {
+            return (Boolean) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Boolean", defaultValue, e);
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or (byte) 0 if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a byte value
+     */
+    public byte getByte(String key) {
+        unparcel();
+        return getByte(key, (byte) 0);
+    }
+
+    /**
+     * Returns the value associated with the given key, or defaultValue if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a byte value
+     */
+    public Byte getByte(String key, byte defaultValue) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return defaultValue;
+        }
+        try {
+            return (Byte) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Byte", defaultValue, e);
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or false if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a char value
+     */
+    public char getChar(String key) {
+        unparcel();
+        return getChar(key, (char) 0);
+    }
+
+    /**
+     * Returns the value associated with the given key, or (char) 0 if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a char value
+     */
+    public char getChar(String key, char defaultValue) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return defaultValue;
+        }
+        try {
+            return (Character) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Character", defaultValue, e);
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or (short) 0 if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a short value
+     */
+    public short getShort(String key) {
+        unparcel();
+        return getShort(key, (short) 0);
+    }
+
+    /**
+     * Returns the value associated with the given key, or defaultValue if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a short value
+     */
+    public short getShort(String key, short defaultValue) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return defaultValue;
+        }
+        try {
+            return (Short) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Short", defaultValue, e);
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or 0 if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return an int value
+     */
+    public int getInt(String key) {
+        unparcel();
+        return getInt(key, 0);
+    }
+
+    /**
+     * Returns the value associated with the given key, or defaultValue if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return an int value
+     */
+    public int getInt(String key, int defaultValue) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return defaultValue;
+        }
+        try {
+            return (Integer) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Integer", defaultValue, e);
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or 0L if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a long value
+     */
+    public long getLong(String key) {
+        unparcel();
+        return getLong(key, 0L);
+    }
+
+    /**
+     * Returns the value associated with the given key, or defaultValue if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a long value
+     */
+    public long getLong(String key, long defaultValue) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return defaultValue;
+        }
+        try {
+            return (Long) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Long", defaultValue, e);
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or 0.0f if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a float value
+     */
+    public float getFloat(String key) {
+        unparcel();
+        return getFloat(key, 0.0f);
+    }
+
+    /**
+     * Returns the value associated with the given key, or defaultValue if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a float value
+     */
+    public float getFloat(String key, float defaultValue) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return defaultValue;
+        }
+        try {
+            return (Float) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Float", defaultValue, e);
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or 0.0 if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a double value
+     */
+    public double getDouble(String key) {
+        unparcel();
+        return getDouble(key, 0.0);
+    }
+
+    /**
+     * Returns the value associated with the given key, or defaultValue if
+     * no mapping of the desired type exists for the given key.
+     *
+     * @param key a String
+     * @return a double value
+     */
+    public double getDouble(String key, double defaultValue) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return defaultValue;
+        }
+        try {
+            return (Double) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Double", defaultValue, e);
+            return defaultValue;
+        }
+    }
+
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a String value, or null
+     */
+    public String getString(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (String) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "String", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a CharSequence value, or null
+     */
+    public CharSequence getCharSequence(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (CharSequence) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "CharSequence", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a Bundle value, or null
+     */
+    public Bundle getBundle(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (Bundle) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Bundle", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a Parcelable value, or null
+     */
+    public <T extends Parcelable> T getParcelable(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (T) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Parcelable", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a Parcelable[] value, or null
+     */
+    public Parcelable[] getParcelableArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (Parcelable[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Parcelable[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return an ArrayList<T> value, or null
+     */
+    public <T extends Parcelable> ArrayList<T> getParcelableArrayList(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (ArrayList<T>) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "ArrayList", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     *
+     * @return a SparseArray of T values, or null
+     */
+    public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (SparseArray<T>) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "SparseArray", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a Serializable value, or null
+     */
+    public Serializable getSerializable(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (Serializable) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "Serializable", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return an ArrayList<String> value, or null
+     */
+    public ArrayList<Integer> getIntegerArrayList(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (ArrayList<Integer>) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "ArrayList<Integer>", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return an ArrayList<String> value, or null
+     */
+    public ArrayList<String> getStringArrayList(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (ArrayList<String>) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "ArrayList<String>", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a boolean[] value, or null
+     */
+    public boolean[] getBooleanArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (boolean[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "byte[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a byte[] value, or null
+     */
+    public byte[] getByteArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (byte[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "byte[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a short[] value, or null
+     */
+    public short[] getShortArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (short[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "short[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a char[] value, or null
+     */
+    public char[] getCharArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (char[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "char[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return an int[] value, or null
+     */
+    public int[] getIntArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (int[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "int[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a long[] value, or null
+     */
+    public long[] getLongArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (long[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "long[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a float[] value, or null
+     */
+    public float[] getFloatArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (float[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "float[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a double[] value, or null
+     */
+    public double[] getDoubleArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (double[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "double[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return a String[] value, or null
+     */
+    public String[] getStringArray(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (String[]) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "String[]", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if
+     * no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key.
+     *
+     * @param key a String, or null
+     * @return an IBinder value, or null
+     *
+     * @deprecated
+     * @hide
+     */
+    @Deprecated
+    public IBinder getIBinder(String key) {
+        unparcel();
+        Object o = mMap.get(key);
+        if (o == null) {
+            return null;
+        }
+        try {
+            return (IBinder) o;
+        } catch (ClassCastException e) {
+            typeWarning(key, o, "IBinder", e);
+            return null;
+        }
+    }
+
+    public static final Parcelable.Creator<Bundle> CREATOR =
+        new Parcelable.Creator<Bundle>() {
+        public Bundle createFromParcel(Parcel in) {
+            return in.readBundle();
+        }
+
+        public Bundle[] newArray(int size) {
+            return new Bundle[size];
+        }
+    };
+
+    /**
+     * Report the nature of this Parcelable's contents
+     */
+    public int describeContents() {
+        int mask = 0;
+        if (hasFileDescriptors()) {
+            mask |= Parcelable.CONTENTS_FILE_DESCRIPTOR;
+        }
+        return mask;
+    }
+    
+    /**
+     * Writes the Bundle contents to a Parcel, typically in order for
+     * it to be passed through an IBinder connection.
+     * @param parcel The parcel to copy this bundle to.
+     */
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeBundle(this);
+    }
+
+    /**
+     * Reads the Parcel contents into this Bundle, typically in order for
+     * it to be passed through an IBinder connection.
+     * @param parcel The parcel to overwrite this bundle from.
+     */
+    public void readFromParcel(Parcel parcel) {
+        mParcelledData = parcel;
+        mHasFds = mParcelledData.hasFileDescriptors();
+        mFdsKnown = true;
+    }
+
+    @Override
+    public synchronized String toString() {
+        if (mParcelledData != null) {
+            return "Bundle[mParcelledData.dataSize=" +
+                    mParcelledData.dataSize() + "]";
+        }
+        return "Bundle[" + mMap.toString() + "]";
+    }
+}
diff --git a/core/java/android/os/ConditionVariable.java b/core/java/android/os/ConditionVariable.java
new file mode 100644
index 0000000..95a9259
--- /dev/null
+++ b/core/java/android/os/ConditionVariable.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * Class that implements the condition variable locking paradigm.
+ *
+ * <p>
+ * This differs from the built-in java.lang.Object wait() and notify()
+ * in that this class contains the condition to wait on itself.  That means
+ * open(), close() and block() are sticky.  If open() is called before block(),
+ * block() will not block, and instead return immediately.
+ *
+ * <p>
+ * This class uses itself is at the object to wait on, so if you wait()
+ * or notify() on a ConditionVariable, the results are undefined.
+ */
+public class ConditionVariable
+{
+    private volatile boolean mCondition;
+
+    /**
+     * Create the ConditionVariable in the default closed state.
+     */
+    public ConditionVariable()
+    {
+        mCondition = false;
+    }
+
+    /**
+     * Create the ConditionVariable with the given state.
+     * 
+     * <p>
+     * Pass true for opened and false for closed.
+     */
+    public ConditionVariable(boolean state)
+    {
+        mCondition = state;
+    }
+
+    /**
+     * Open the condition, and release all threads that are blocked.
+     *
+     * <p>
+     * Any threads that later approach block() will not block unless close()
+     * is called.
+     */
+    public void open()
+    {
+        synchronized (this) {
+            boolean old = mCondition;
+            mCondition = true;
+            if (!old) {
+                this.notifyAll();
+            }
+        }
+    }
+
+    /**
+     * Reset the condition to the closed state.
+     *
+     * <p>
+     * Any threads that call block() will block until someone calls open.
+     */
+    public void close()
+    {
+        synchronized (this) {
+            mCondition = false;
+        }
+    }
+
+    /**
+     * Block the current thread until the condition is opened.
+     *
+     * <p>
+     * If the condition is already opened, return immediately.
+     */
+    public void block()
+    {
+        synchronized (this) {
+            while (!mCondition) {
+                try {
+                    this.wait();
+                }
+                catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Block the current thread until the condition is opened or until
+     * timeout milliseconds have passed.
+     *
+     * <p>
+     * If the condition is already opened, return immediately.
+     *
+     * @param timeout the minimum time to wait in milliseconds.
+     *
+     * @return true if the condition was opened, false if the call returns
+     * because of the timeout.
+     */
+    public boolean block(long timeout)
+    {
+        // Object.wait(0) means wait forever, to mimic this, we just
+        // call the other block() method in that case.  It simplifies
+        // this code for the common case.
+        if (timeout != 0) {
+            synchronized (this) {
+                long now = System.currentTimeMillis();
+                long end = now + timeout;
+                while (!mCondition && now < end) {
+                    try {
+                        this.wait(end-now);
+                    }
+                    catch (InterruptedException e) {
+                    }
+                    now = System.currentTimeMillis();
+                }
+                return mCondition;
+            }
+        } else {
+            this.block();
+            return true;
+        }
+    }
+}
diff --git a/core/java/android/os/CountDownTimer.java b/core/java/android/os/CountDownTimer.java
new file mode 100644
index 0000000..0c5c615
--- /dev/null
+++ b/core/java/android/os/CountDownTimer.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2008 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;
+
+/**
+ * Schedule a countdown until a time in the future, with
+ * regular notifications on intervals along the way.
+ *
+ * Example of showing a 30 second countdown in a text field:
+ *
+ * <pre class="prettyprint">
+ * new CountdownTimer(30000, 1000) {
+ *
+ *     public void onTick(long millisUntilFinished) {
+ *         mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
+ *     }
+ *
+ *     public void onFinish() {
+ *         mTextField.setText("done!");
+ *     }
+ *  }.start();
+ * </pre>
+ *
+ * The calls to {@link #onTick(long)} are synchronized to this object so that
+ * one call to {@link #onTick(long)} won't ever occur before the previous
+ * callback is complete.  This is only relevant when the implementation of
+ * {@link #onTick(long)} takes an amount of time to execute that is significant
+ * compared to the countdown interval.
+ */
+public abstract class CountDownTimer {
+
+    /**
+     * Millis since epoch when alarm should stop.
+     */
+    private final long mMillisInFuture;
+
+    /**
+     * The interval in millis that the user receives callbacks
+     */
+    private final long mCountdownInterval;
+
+    private long mStopTimeInFuture;
+
+    /**
+     * @param millisInFuture The number of millis in the future from the call
+     *   to {@link #start()} until the countdown is done and {@link #onFinish()}
+     *   is called.
+     * @param countDownInterval The interval along the way to receive
+     *   {@link #onTick(long)} callbacks.
+     */
+    public CountDownTimer(long millisInFuture, long countDownInterval) {
+        mMillisInFuture = millisInFuture;
+        mCountdownInterval = countDownInterval;
+    }
+
+    /**
+     * Cancel the countdown.
+     */
+    public final void cancel() {
+        mHandler.removeMessages(MSG);
+    }
+
+    /**
+     * Start the countdown.
+     */
+    public synchronized final CountDownTimer start() {
+        if (mMillisInFuture <= 0) {
+            onFinish();
+            return this;
+        }
+        mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
+        mHandler.sendMessage(mHandler.obtainMessage(MSG));
+        return this;
+    }
+
+
+    /**
+     * Callback fired on regular interval.
+     * @param millisUntilFinished The amount of time until finished.
+     */
+    public abstract void onTick(long millisUntilFinished);
+
+    /**
+     * Callback fired when the time is up.
+     */
+    public abstract void onFinish();
+
+
+    private static final int MSG = 1;
+
+
+    // handles counting down
+    private Handler mHandler = new Handler() {
+
+        @Override
+        public void handleMessage(Message msg) {
+
+            synchronized (CountDownTimer.this) {
+                final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
+
+                if (millisLeft <= 0) {
+                    onFinish();
+                } else if (millisLeft < mCountdownInterval) {
+                    // no tick, just delay until done
+                    sendMessageDelayed(obtainMessage(MSG), millisLeft);
+                } else {
+                    long lastTickStart = SystemClock.elapsedRealtime();
+                    onTick(millisLeft);
+
+                    // take into account user's onTick taking time to execute
+                    long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
+
+                    // special case: user's onTick took more than interval to
+                    // complete, skip to next interval
+                    while (delay < 0) delay += mCountdownInterval;
+
+                    sendMessageDelayed(obtainMessage(MSG), delay);
+                }
+            }
+        }
+    };
+}
diff --git a/core/java/android/os/DeadObjectException.java b/core/java/android/os/DeadObjectException.java
new file mode 100644
index 0000000..94c5387
--- /dev/null
+++ b/core/java/android/os/DeadObjectException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2006 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.os.RemoteException;
+
+/**
+ * The object you are calling has died, because its hosting process
+ * no longer exists.
+ */
+public class DeadObjectException extends RemoteException {
+    public DeadObjectException() {
+        super();
+    }
+}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
new file mode 100644
index 0000000..950bb09
--- /dev/null
+++ b/core/java/android/os/Debug.java
@@ -0,0 +1,717 @@
+/*
+ * 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 java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+
+import org.apache.harmony.dalvik.ddmc.Chunk;
+import org.apache.harmony.dalvik.ddmc.ChunkHandler;
+import org.apache.harmony.dalvik.ddmc.DdmServer;
+
+import dalvik.bytecode.Opcodes;
+import dalvik.system.VMDebug;
+
+
+/**
+ * Provides various debugging functions for Android applications, including
+ * tracing and allocation counts.
+ * <p><strong>Logging Trace Files</strong></p>
+ * <p>Debug can create log files that give details about an application, such as
+ * a call stack and start/stop times for any running methods. See <a
+href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
+ * information about reading trace files. To start logging trace files, call one
+ * of the startMethodTracing() methods. To stop tracing, call
+ * {@link #stopMethodTracing()}.
+ */
+public final class Debug
+{
+    /**
+     * Flags for startMethodTracing().  These can be ORed together.
+     *
+     * TRACE_COUNT_ALLOCS adds the results from startAllocCounting to the
+     * trace key file.
+     */
+    public static final int TRACE_COUNT_ALLOCS  = VMDebug.TRACE_COUNT_ALLOCS;
+
+    /**
+     * Flags for printLoadedClasses().  Default behavior is to only show
+     * the class name.
+     */
+    public static final int SHOW_FULL_DETAIL    = 1;
+    public static final int SHOW_CLASSLOADER    = (1 << 1);
+    public static final int SHOW_INITIALIZED    = (1 << 2);
+
+    // set/cleared by waitForDebugger()
+    private static volatile boolean mWaiting = false;
+
+    private Debug() {}
+
+    /*
+     * How long to wait for the debugger to finish sending requests.  I've
+     * seen this hit 800msec on the device while waiting for a response
+     * to travel over USB and get processed, so we take that and add
+     * half a second.
+     */
+    private static final int MIN_DEBUGGER_IDLE = 1300;      // msec
+
+    /* how long to sleep when polling for activity */
+    private static final int SPIN_DELAY = 200;              // msec
+
+    /**
+     * Default trace file path and file
+     */
+    private static final String DEFAULT_TRACE_PATH_PREFIX = "/sdcard/";
+    private static final String DEFAULT_TRACE_BODY = "dmtrace";
+    private static final String DEFAULT_TRACE_EXTENSION = ".trace";
+    private static final String DEFAULT_TRACE_FILE_PATH =
+        DEFAULT_TRACE_PATH_PREFIX + DEFAULT_TRACE_BODY
+        + DEFAULT_TRACE_EXTENSION;
+
+
+    /**
+     * This class is used to retrieved various statistics about the memory mappings for this
+     * process. The returns info broken down by dalvik, native, and other. All results are in kB.
+     */
+    public static class MemoryInfo {
+        /** The proportional set size for dalvik. */
+        public int dalvikPss;
+        /** The private dirty pages used by dalvik. */
+        public int dalvikPrivateDirty;
+        /** The shared dirty pages used by dalvik. */
+        public int dalvikSharedDirty;
+
+        /** The proportional set size for the native heap. */
+        public int nativePss;
+        /** The private dirty pages used by the native heap. */
+        public int nativePrivateDirty;
+        /** The shared dirty pages used by the native heap. */
+        public int nativeSharedDirty;
+
+        /** The proportional set size for everything else. */
+        public int otherPss;
+        /** The private dirty pages used by everything else. */
+        public int otherPrivateDirty;
+        /** The shared dirty pages used by everything else. */
+        public int otherSharedDirty;
+    }
+
+
+    /**
+     * Wait until a debugger attaches.  As soon as the debugger attaches,
+     * this returns, so you will need to place a breakpoint after the
+     * waitForDebugger() call if you want to start tracing immediately.
+     */
+    public static void waitForDebugger() {
+        if (!VMDebug.isDebuggingEnabled()) {
+            //System.out.println("debugging not enabled, not waiting");
+            return;
+        }
+        if (isDebuggerConnected())
+            return;
+
+        // if DDMS is listening, inform them of our plight
+        System.out.println("Sending WAIT chunk");
+        byte[] data = new byte[] { 0 };     // 0 == "waiting for debugger"
+        Chunk waitChunk = new Chunk(ChunkHandler.type("WAIT"), data, 0, 1);
+        DdmServer.sendChunk(waitChunk);
+
+        mWaiting = true;
+        while (!isDebuggerConnected()) {
+            try { Thread.sleep(SPIN_DELAY); }
+            catch (InterruptedException ie) {}
+        }
+        mWaiting = false;
+
+        System.out.println("Debugger has connected");
+
+        /*
+         * There is no "ready to go" signal from the debugger, and we're
+         * not allowed to suspend ourselves -- the debugger expects us to
+         * be running happily, and gets confused if we aren't.  We need to
+         * allow the debugger a chance to set breakpoints before we start
+         * running again.
+         *
+         * Sit and spin until the debugger has been idle for a short while.
+         */
+        while (true) {
+            long delta = VMDebug.lastDebuggerActivity();
+            if (delta < 0) {
+                System.out.println("debugger detached?");
+                break;
+            }
+
+            if (delta < MIN_DEBUGGER_IDLE) {
+                System.out.println("waiting for debugger to settle...");
+                try { Thread.sleep(SPIN_DELAY); }
+                catch (InterruptedException ie) {}
+            } else {
+                System.out.println("debugger has settled (" + delta + ")");
+                break;
+            }
+        }
+    }
+
+    /**
+     * Returns "true" if one or more threads is waiting for a debugger
+     * to attach.
+     */
+    public static boolean waitingForDebugger() {
+        return mWaiting;
+    }
+
+    /**
+     * Determine if a debugger is currently attached.
+     */
+    public static boolean isDebuggerConnected() {
+        return VMDebug.isDebuggerConnected();
+    }
+
+    /**
+     * Change the JDWP port.
+     *
+     * @deprecated no longer needed or useful
+     */
+    @Deprecated
+    public static void changeDebugPort(int port) {}
+
+    /**
+     * This is the pathname to the sysfs file that enables and disables
+     * tracing on the qemu emulator.
+     */
+    private static final String SYSFS_QEMU_TRACE_STATE = "/sys/qemu_trace/state";
+
+    /**
+     * Enable qemu tracing. For this to work requires running everything inside
+     * the qemu emulator; otherwise, this method will have no effect. The trace
+     * file is specified on the command line when the emulator is started. For
+     * example, the following command line <br />
+     * <code>emulator -trace foo</code><br />
+     * will start running the emulator and create a trace file named "foo". This
+     * method simply enables writing the trace records to the trace file.
+     *
+     * <p>
+     * The main differences between this and {@link #startMethodTracing()} are
+     * that tracing in the qemu emulator traces every cpu instruction of every
+     * process, including kernel code, so we have more complete information,
+     * including all context switches. We can also get more detailed information
+     * such as cache misses. The sequence of calls is determined by
+     * post-processing the instruction trace. The qemu tracing is also done
+     * without modifying the application or perturbing the timing of calls
+     * because no instrumentation is added to the application being traced.
+     * </p>
+     *
+     * <p>
+     * One limitation of using this method compared to using
+     * {@link #startMethodTracing()} on the real device is that the emulator
+     * does not model all of the real hardware effects such as memory and
+     * bus contention.  The emulator also has a simple cache model and cannot
+     * capture all the complexities of a real cache.
+     * </p>
+     */
+    public static void startNativeTracing() {
+        // Open the sysfs file for writing and write "1" to it.
+        PrintWriter outStream = null;
+        try {
+            FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
+            outStream = new PrintWriter(new OutputStreamWriter(fos));
+            outStream.println("1");
+        } catch (Exception e) {
+        } finally {
+            if (outStream != null)
+                outStream.close();
+        }
+
+        VMDebug.startEmulatorTracing();
+    }
+
+    /**
+     * Stop qemu tracing.  See {@link #startNativeTracing()} to start tracing.
+     *
+     * <p>Tracing can be started and stopped as many times as desired.  When
+     * the qemu emulator itself is stopped then the buffered trace records
+     * are flushed and written to the trace file.  In fact, it is not necessary
+     * to call this method at all; simply killing qemu is sufficient.  But
+     * starting and stopping a trace is useful for examining a specific
+     * region of code.</p>
+     */
+    public static void stopNativeTracing() {
+        VMDebug.stopEmulatorTracing();
+
+        // Open the sysfs file for writing and write "0" to it.
+        PrintWriter outStream = null;
+        try {
+            FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
+            outStream = new PrintWriter(new OutputStreamWriter(fos));
+            outStream.println("0");
+        } catch (Exception e) {
+            // We could print an error message here but we probably want
+            // to quietly ignore errors if we are not running in the emulator.
+        } finally {
+            if (outStream != null)
+                outStream.close();
+        }
+    }
+
+    /**
+     * Enable "emulator traces", in which information about the current
+     * method is made available to the "emulator -trace" feature.  There
+     * is no corresponding "disable" call -- this is intended for use by
+     * the framework when tracing should be turned on and left that way, so
+     * that traces captured with F9/F10 will include the necessary data.
+     *
+     * This puts the VM into "profile" mode, which has performance
+     * consequences.
+     *
+     * To temporarily enable tracing, use {@link #startNativeTracing()}.
+     */
+    public static void enableEmulatorTraceOutput() {
+        VMDebug.startEmulatorTracing();
+    }
+
+    /**
+     * Start method tracing with default log name and buffer size. See <a
+href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
+     * information about reading these files. Call stopMethodTracing() to stop
+     * tracing.
+     */
+    public static void startMethodTracing() {
+        VMDebug.startMethodTracing(DEFAULT_TRACE_FILE_PATH, 0, 0);
+    }
+
+    /**
+     * Start method tracing, specifying the trace log file name.  The trace
+     * file will be put under "/sdcard" unless an absolute path is given.
+     * See <a
+       href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
+     * information about reading trace files.
+     *
+     * @param traceName Name for the trace log file to create.
+     * If no name argument is given, this value defaults to "/sdcard/dmtrace.trace".
+     * If the files already exist, they will be truncated.
+     * If the trace file given does not end in ".trace", it will be appended for you.
+     */
+    public static void startMethodTracing(String traceName) {
+        startMethodTracing(traceName, 0, 0);
+    }
+
+    /**
+     * Start method tracing, specifying the trace log file name and the
+     * buffer size. The trace files will be put under "/sdcard" unless an
+     * absolute path is given. See <a
+       href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
+     * information about reading trace files.
+     * @param traceName    Name for the trace log file to create.
+     * If no name argument is given, this value defaults to "/sdcard/dmtrace.trace".
+     * If the files already exist, they will be truncated.
+     * If the trace file given does not end in ".trace", it will be appended for you.
+     *
+     * @param bufferSize    The maximum amount of trace data we gather. If not given, it defaults to 8MB.
+     */
+    public static void startMethodTracing(String traceName, int bufferSize) {
+        startMethodTracing(traceName, bufferSize, 0);
+    }
+
+    /**
+     * Start method tracing, specifying the trace log file name and the
+     * buffer size. The trace files will be put under "/sdcard" unless an
+     * absolute path is given. See <a
+       href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
+     * information about reading trace files.
+     *
+     * <p>
+     * When method tracing is enabled, the VM will run more slowly than
+     * usual, so the timings from the trace files should only be considered
+     * in relative terms (e.g. was run #1 faster than run #2).  The times
+     * for native methods will not change, so don't try to use this to
+     * compare the performance of interpreted and native implementations of the
+     * same method.  As an alternative, consider using "native" tracing
+     * in the emulator via {@link #startNativeTracing()}.
+     * </p>
+     *
+     * @param traceName    Name for the trace log file to create.
+     * If no name argument is given, this value defaults to "/sdcard/dmtrace.trace".
+     * If the files already exist, they will be truncated.
+     * If the trace file given does not end in ".trace", it will be appended for you.
+     * @param bufferSize    The maximum amount of trace data we gather. If not given, it defaults to 8MB.
+     */
+    public static void startMethodTracing(String traceName, int bufferSize,
+        int flags) {
+
+        String pathName = traceName;
+        if (pathName.charAt(0) != '/')
+            pathName = DEFAULT_TRACE_PATH_PREFIX + pathName;
+        if (!pathName.endsWith(DEFAULT_TRACE_EXTENSION))
+            pathName = pathName + DEFAULT_TRACE_EXTENSION;
+
+        VMDebug.startMethodTracing(pathName, bufferSize, flags);
+    }
+
+    /**
+     * Stop method tracing.
+     */
+    public static void stopMethodTracing() {
+        VMDebug.stopMethodTracing();
+    }
+
+    /**
+     * Get an indication of thread CPU usage.  The value returned
+     * indicates the amount of time that the current thread has spent
+     * executing code or waiting for certain types of I/O.
+     *
+     * The time is expressed in nanoseconds, and is only meaningful
+     * when compared to the result from an earlier call.  Note that
+     * nanosecond resolution does not imply nanosecond accuracy.
+     *
+     * On system which don't support this operation, the call returns -1.
+     */
+    public static long threadCpuTimeNanos() {
+        return VMDebug.threadCpuTimeNanos();
+    }
+
+    /**
+     * Count the number and aggregate size of memory allocations between
+     * two points.
+     *
+     * The "start" function resets the counts and enables counting.  The
+     * "stop" function disables the counting so that the analysis code
+     * doesn't cause additional allocations.  The "get" function returns
+     * the specified value.
+     *
+     * Counts are kept for the system as a whole and for each thread.
+     * The per-thread counts for threads other than the current thread
+     * are not cleared by the "reset" or "start" calls.
+     */
+    public static void startAllocCounting() {
+        VMDebug.startAllocCounting();
+    }
+    public static void stopAllocCounting() {
+        VMDebug.stopAllocCounting();
+    }
+
+    public static int getGlobalAllocCount() {
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
+    }
+    public static int getGlobalAllocSize() {
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
+    }
+    public static int getGlobalFreedCount() {
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
+    }
+    public static int getGlobalFreedSize() {
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
+    }
+    public static int getGlobalExternalAllocCount() {
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_EXT_ALLOCATED_OBJECTS);
+    }
+    public static int getGlobalExternalAllocSize() {
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_EXT_ALLOCATED_BYTES);
+    }
+    public static int getGlobalExternalFreedCount() {
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_EXT_FREED_OBJECTS);
+    }
+    public static int getGlobalExternalFreedSize() {
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_EXT_FREED_BYTES);
+    }
+    public static int getGlobalGcInvocationCount() {
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
+    }
+    public static int getThreadAllocCount() {
+        return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
+    }
+    public static int getThreadAllocSize() {
+        return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
+    }
+    public static int getThreadExternalAllocCount() {
+        return VMDebug.getAllocCount(VMDebug.KIND_THREAD_EXT_ALLOCATED_OBJECTS);
+    }
+    public static int getThreadExternalAllocSize() {
+        return VMDebug.getAllocCount(VMDebug.KIND_THREAD_EXT_ALLOCATED_BYTES);
+    }
+    public static int getThreadGcInvocationCount() {
+        return VMDebug.getAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
+    }
+
+    public static void resetGlobalAllocCount() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
+    }
+    public static void resetGlobalAllocSize() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
+    }
+    public static void resetGlobalFreedCount() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
+    }
+    public static void resetGlobalFreedSize() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
+    }
+    public static void resetGlobalExternalAllocCount() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_EXT_ALLOCATED_OBJECTS);
+    }
+    public static void resetGlobalExternalAllocSize() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_EXT_ALLOCATED_BYTES);
+    }
+    public static void resetGlobalExternalFreedCount() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_EXT_FREED_OBJECTS);
+    }
+    public static void resetGlobalExternalFreedSize() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_EXT_FREED_BYTES);
+    }
+    public static void resetGlobalGcInvocationCount() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
+    }
+    public static void resetThreadAllocCount() {
+        VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
+    }
+    public static void resetThreadAllocSize() {
+        VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
+    }
+    public static void resetThreadExternalAllocCount() {
+        VMDebug.resetAllocCount(VMDebug.KIND_THREAD_EXT_ALLOCATED_OBJECTS);
+    }
+    public static void resetThreadExternalAllocSize() {
+        VMDebug.resetAllocCount(VMDebug.KIND_THREAD_EXT_ALLOCATED_BYTES);
+    }
+    public static void resetThreadGcInvocationCount() {
+        VMDebug.resetAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
+    }
+    public static void resetAllCounts() {
+        VMDebug.resetAllocCount(VMDebug.KIND_ALL_COUNTS);
+    }
+
+    /**
+     * Returns the size of the native heap.
+     * @return The size of the native heap in bytes.
+     */
+    public static native long getNativeHeapSize();
+
+    /**
+     * Returns the amount of allocated memory in the native heap.
+     * @return The allocated size in bytes.
+     */
+    public static native long getNativeHeapAllocatedSize();
+
+    /**
+     * Returns the amount of free memory in the native heap.
+     * @return The freed size in bytes.
+     */
+    public static native long getNativeHeapFreeSize();
+
+    /**
+     * Retrieves information about this processes memory usages. This information is broken down by
+     * how much is in use by dalivk, the native heap, and everything else.
+     */
+    public static native void getMemoryInfo(MemoryInfo memoryInfo);
+
+    /**
+     * Establish an object allocation limit in the current thread.  Useful
+     * for catching regressions in code that is expected to operate
+     * without causing any allocations.
+     *
+     * Pass in the maximum number of allowed allocations.  Use -1 to disable
+     * the limit.  Returns the previous limit.
+     *
+     * The preferred way to use this is:
+     *
+     *  int prevLimit = -1;
+     *  try {
+     *      prevLimit = Debug.setAllocationLimit(0);
+     *      ... do stuff that's not expected to allocate memory ...
+     *  } finally {
+     *      Debug.setAllocationLimit(prevLimit);
+     *  }
+     *
+     * This allows limits to be nested.  The try/finally ensures that the
+     * limit is reset if something fails.
+     *
+     * Exceeding the limit causes a dalvik.system.AllocationLimitError to
+     * be thrown from a memory allocation call.  The limit is reset to -1
+     * when this happens.
+     *
+     * The feature may be disabled in the VM configuration.  If so, this
+     * call has no effect, and always returns -1.
+     */
+    public static int setAllocationLimit(int limit) {
+        return VMDebug.setAllocationLimit(limit);
+    }
+
+    /**
+     * Establish a global object allocation limit.  This is similar to
+     * {@link #setAllocationLimit(int)} but applies to all threads in
+     * the VM.  It will coexist peacefully with per-thread limits.
+     *
+     * [ The value of "limit" is currently restricted to 0 (no allocations
+     *   allowed) or -1 (no global limit).  This may be changed in a future
+     *   release. ]
+     */
+    public static int setGlobalAllocationLimit(int limit) {
+        if (limit != 0 && limit != -1)
+            throw new IllegalArgumentException("limit must be 0 or -1");
+        return VMDebug.setGlobalAllocationLimit(limit);
+    }
+
+    /**
+     * Dump a list of all currently loaded class to the log file.
+     *
+     * @param flags See constants above.
+     */
+    public static void printLoadedClasses(int flags) {
+        VMDebug.printLoadedClasses(flags);
+    }
+
+    /**
+     * Get the number of loaded classes.
+     * @return the number of loaded classes.
+     */
+    public static int getLoadedClassCount() {
+        return VMDebug.getLoadedClassCount();
+    }
+
+    /**
+     * Dump "hprof" data to the specified file.  This will cause a GC.
+     *
+     * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof").
+     * @throws UnsupportedOperationException if the VM was built without
+     *         HPROF support.
+     * @throws IOException if an error occurs while opening or writing files.
+     */
+    public static void dumpHprofData(String fileName) throws IOException {
+        VMDebug.dumpHprofData(fileName);
+    }
+
+    /**
+     * Returns the number of sent transactions from this process.
+     * @return The number of sent transactions or -1 if it could not read t.
+     */
+    public static native int getBinderSentTransactions();
+
+    /**
+     * Returns the number of received transactions from the binder driver.
+     * @return The number of received transactions or -1 if it could not read the stats.
+     */
+    public static native int getBinderReceivedTransactions();
+
+    /**
+     * Returns the number of active local Binder objects that exist in the
+     * current process.
+     */
+    public static final native int getBinderLocalObjectCount();
+
+    /**
+     * Returns the number of references to remote proxy Binder objects that
+     * exist in the current process.
+     */
+    public static final native int getBinderProxyObjectCount();
+
+    /**
+     * Returns the number of death notification links to Binder objects that
+     * exist in the current process.
+     */
+    public static final native int getBinderDeathObjectCount();
+
+    /**
+     * API for gathering and querying instruction counts.
+     *
+     * Example usage:
+     *   Debug.InstructionCount icount = new Debug.InstructionCount();
+     *   icount.resetAndStart();
+     *    [... do lots of stuff ...]
+     *   if (icount.collect()) {
+     *       System.out.println("Total instructions executed: "
+     *           + icount.globalTotal());
+     *       System.out.println("Method invocations: "
+     *           + icount.globalMethodInvocations());
+     *   }
+     */
+    public static class InstructionCount {
+        private static final int NUM_INSTR = 256;
+
+        private int[] mCounts;
+
+        public InstructionCount() {
+            mCounts = new int[NUM_INSTR];
+        }
+
+        /**
+         * Reset counters and ensure counts are running.  Counts may
+         * have already been running.
+         *
+         * @return true if counting was started
+         */
+        public boolean resetAndStart() {
+            try {
+                VMDebug.startInstructionCounting();
+                VMDebug.resetInstructionCount();
+            } catch (UnsupportedOperationException uoe) {
+                return false;
+            }
+            return true;
+        }
+
+        /**
+         * Collect instruction counts.  May or may not stop the
+         * counting process.
+         */
+        public boolean collect() {
+            try {
+                VMDebug.stopInstructionCounting();
+                VMDebug.getInstructionCount(mCounts);
+            } catch (UnsupportedOperationException uoe) {
+                return false;
+            }
+            return true;
+        }
+
+        /**
+         * Return the total number of instructions executed globally (i.e. in
+         * all threads).
+         */
+        public int globalTotal() {
+            int count = 0;
+            for (int i = 0; i < NUM_INSTR; i++)
+                count += mCounts[i];
+            return count;
+        }
+
+        /**
+         * Return the total number of method-invocation instructions
+         * executed globally.
+         */
+        public int globalMethodInvocations() {
+            int count = 0;
+
+            //count += mCounts[Opcodes.OP_EXECUTE_INLINE];
+            count += mCounts[Opcodes.OP_INVOKE_VIRTUAL];
+            count += mCounts[Opcodes.OP_INVOKE_SUPER];
+            count += mCounts[Opcodes.OP_INVOKE_DIRECT];
+            count += mCounts[Opcodes.OP_INVOKE_STATIC];
+            count += mCounts[Opcodes.OP_INVOKE_INTERFACE];
+            count += mCounts[Opcodes.OP_INVOKE_VIRTUAL_RANGE];
+            count += mCounts[Opcodes.OP_INVOKE_SUPER_RANGE];
+            count += mCounts[Opcodes.OP_INVOKE_DIRECT_RANGE];
+            count += mCounts[Opcodes.OP_INVOKE_STATIC_RANGE];
+            count += mCounts[Opcodes.OP_INVOKE_INTERFACE_RANGE];
+            //count += mCounts[Opcodes.OP_INVOKE_DIRECT_EMPTY];
+            count += mCounts[Opcodes.OP_INVOKE_VIRTUAL_QUICK];
+            count += mCounts[Opcodes.OP_INVOKE_VIRTUAL_QUICK_RANGE];
+            count += mCounts[Opcodes.OP_INVOKE_SUPER_QUICK];
+            count += mCounts[Opcodes.OP_INVOKE_SUPER_QUICK_RANGE];
+            return count;
+        }
+    };
+}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
new file mode 100644
index 0000000..f761e8e
--- /dev/null
+++ b/core/java/android/os/Environment.java
@@ -0,0 +1,131 @@
+/*
+ * 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 java.io.File;
+
+/**
+ * Provides access to environment variables.
+ */
+public class Environment {
+
+    private static final File ROOT_DIRECTORY
+            = getDirectory("ANDROID_ROOT", "/system");
+
+    /**
+     * Gets the Android root directory.
+     */
+    public static File getRootDirectory() {
+        return ROOT_DIRECTORY;
+    }
+
+    private static final File DATA_DIRECTORY
+            = getDirectory("ANDROID_DATA", "/data");
+
+    private static final File EXTERNAL_STORAGE_DIRECTORY
+            = getDirectory("EXTERNAL_STORAGE", "/sdcard");
+
+    private static final File DOWNLOAD_CACHE_DIRECTORY
+            = getDirectory("DOWNLOAD_CACHE", "/cache");
+
+    /**
+     * Gets the Android data directory.
+     */
+    public static File getDataDirectory() {
+        return DATA_DIRECTORY;
+    }
+
+    /**
+     * Gets the Android external storage directory.
+     */
+    public static File getExternalStorageDirectory() {
+        return EXTERNAL_STORAGE_DIRECTORY;
+    }
+
+    /**
+     * Gets the Android Download/Cache content directory.
+     */
+    public static File getDownloadCacheDirectory() {
+        return DOWNLOAD_CACHE_DIRECTORY;
+    }
+
+    /**
+     * getExternalStorageState() returns MEDIA_REMOVED if the media is not present. 
+     */
+    public static final String MEDIA_REMOVED = "removed";
+     
+    /**
+     * getExternalStorageState() returns MEDIA_UNMOUNTED if the media is present
+     * but not mounted. 
+     */
+    public static final String MEDIA_UNMOUNTED = "unmounted";
+
+    /**
+     * getExternalStorageState() returns MEDIA_CHECKING if the media is present
+     * and being disk-checked
+     */
+    public static final String MEDIA_CHECKING = "checking";
+
+    /**
+     * getExternalStorageState() returns MEDIA_NOFS if the media is present
+     * but is blank or is using an unsupported filesystem
+     */
+    public static final String MEDIA_NOFS = "nofs";
+
+    /**
+     * getExternalStorageState() returns MEDIA_MOUNTED if the media is present
+     * and mounted at its mount point with read/write access. 
+     */
+    public static final String MEDIA_MOUNTED = "mounted";
+
+    /**
+     * getExternalStorageState() returns MEDIA_MOUNTED_READ_ONLY if the media is present
+     * and mounted at its mount point with read only access. 
+     */
+    public static final String MEDIA_MOUNTED_READ_ONLY = "mounted_ro";
+
+    /**
+     * getExternalStorageState() returns MEDIA_SHARED if the media is present
+     * not mounted, and shared via USB mass storage. 
+     */
+    public static final String MEDIA_SHARED = "shared";
+
+    /**
+     * getExternalStorageState() returns MEDIA_BAD_REMOVAL if the media was
+     * removed before it was unmounted. 
+     */
+    public static final String MEDIA_BAD_REMOVAL = "bad_removal";
+
+    /**
+     * getExternalStorageState() returns MEDIA_UNMOUNTABLE if the media is present
+     * but cannot be mounted.  Typically this happens if the file system on the
+     * media is corrupted. 
+     */
+    public static final String MEDIA_UNMOUNTABLE = "unmountable";
+
+    /**
+     * Gets the current state of the external storage device.
+     */
+    public static String getExternalStorageState() {
+        return SystemProperties.get("EXTERNAL_STORAGE_STATE", MEDIA_REMOVED);
+    }
+
+    static File getDirectory(String variableName, String defaultPath) {
+        String path = System.getenv(variableName);
+        return path == null ? new File(defaultPath) : new File(path);
+    }
+}
diff --git a/core/java/android/os/Exec.java b/core/java/android/os/Exec.java
new file mode 100644
index 0000000..a50d5fe
--- /dev/null
+++ b/core/java/android/os/Exec.java
@@ -0,0 +1,63 @@
+/*
+ * 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 java.io.FileDescriptor;
+
+/**
+ * @hide
+ * Tools for executing commands.  Not for public consumption.
+ */
+
+public class Exec
+{
+    /**
+     * @param cmd The command to execute
+     * @param arg0 The first argument to the command, may be null
+     * @param arg1 the second argument to the command, may be null
+     * @return the file descriptor of the started process.
+     * 
+     */
+    public static FileDescriptor createSubprocess(
+        String cmd, String arg0, String arg1) {
+        return createSubprocess(cmd, arg0, arg1, null);
+    }
+    
+    /**
+     * @param cmd The command to execute
+     * @param arg0 The first argument to the command, may be null
+     * @param arg1 the second argument to the command, may be null
+     * @param processId A one-element array to which the process ID of the
+     * started process will be written.
+     * @return the file descriptor of the started process.
+     * 
+     */
+     public static native FileDescriptor createSubprocess(
+        String cmd, String arg0, String arg1, int[] processId);
+    
+     public static native void setPtyWindowSize(FileDescriptor fd,
+       int row, int col, int xpixel, int ypixel);
+    /**
+     * Causes the calling thread to wait for the process associated with the
+     * receiver to finish executing.
+     * 
+     * @return The exit value of the Process being waited on
+     * 
+     */
+    public static native int waitFor(int processId);
+}
+
diff --git a/core/java/android/os/FileObserver.java b/core/java/android/os/FileObserver.java
new file mode 100644
index 0000000..d9804ea
--- /dev/null
+++ b/core/java/android/os/FileObserver.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2006 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;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public abstract class FileObserver {
+    public static final int ACCESS = 0x00000001; /* File was accessed */
+    public static final int MODIFY = 0x00000002; /* File was modified */
+    public static final int ATTRIB = 0x00000004; /* Metadata changed */
+    public static final int CLOSE_WRITE = 0x00000008; /*  Writtable file was  closed */
+    public static final int CLOSE_NOWRITE = 0x00000010; /* Unwrittable file closed */
+    public static final int OPEN = 0x00000020; /* File was opened */
+    public static final int MOVED_FROM = 0x00000040; /* File was moved from X */
+    public static final int MOVED_TO = 0x00000080; /* File was moved to Y */
+    public static final int CREATE = 0x00000100; /* Subfile was created */
+    public static final int DELETE = 0x00000200; /* Subfile was deleted */
+    public static final int DELETE_SELF = 0x00000400; /* Self was deleted */
+    public static final int MOVE_SELF = 0x00000800; /* Self was moved */
+    public static final int ALL_EVENTS = ACCESS | MODIFY | ATTRIB | CLOSE_WRITE 
+            | CLOSE_NOWRITE | OPEN | MOVED_FROM | MOVED_TO | DELETE | CREATE
+	    | DELETE_SELF | MOVE_SELF;
+    
+    private static final String LOG_TAG = "FileObserver";
+
+    private static class ObserverThread extends Thread {
+	private HashMap<Integer, WeakReference> m_observers = new HashMap<Integer, WeakReference>();
+	private int m_fd;
+
+	public ObserverThread() {
+	    super("FileObserver");
+	    m_fd = init();
+	}
+
+	public void run() {
+	    observe(m_fd);
+	}
+
+	public int startWatching(String path, int mask, FileObserver observer) {
+	    int wfd = startWatching(m_fd, path, mask);
+
+	    Integer i = new Integer(wfd);
+	    if (wfd >= 0) {
+		synchronized (m_observers) {
+		    m_observers.put(i, new WeakReference(observer));
+		}
+	    }
+
+	    return i;
+	}
+
+	public void stopWatching(int descriptor) {
+	    stopWatching(m_fd, descriptor);
+	}
+
+    public void onEvent(int wfd, int mask, String path) {
+        // look up our observer, fixing up the map if necessary...
+        FileObserver observer;
+
+        synchronized (m_observers) {
+            WeakReference weak = m_observers.get(wfd);
+            observer = (FileObserver) weak.get();
+            if (observer == null) {
+                m_observers.remove(wfd);
+            }
+        }
+
+        // ...then call out to the observer without the sync lock held
+        if (observer != null) {
+            try {
+                observer.onEvent(mask, path);
+            } catch (Throwable throwable) {
+                Log.e(LOG_TAG, "Unhandled throwable " + throwable.toString() + 
+                        " (returned by observer " + observer + ")", throwable);
+                RuntimeInit.crash("FileObserver", throwable);
+            }
+        }
+    }
+
+	private native int init();
+	private native void observe(int fd);
+	private native int startWatching(int fd, String path, int mask);
+	private native void stopWatching(int fd, int wfd);
+    }
+
+    private static ObserverThread s_observerThread;
+
+    static {
+	s_observerThread = new ObserverThread();
+	s_observerThread.start();
+    }
+
+    // instance
+    private String m_path;
+    private Integer m_descriptor;
+    private int m_mask;
+
+    public FileObserver(String path) {
+	this(path, ALL_EVENTS);
+    }
+
+    public FileObserver(String path, int mask) {
+	m_path = path;
+	m_mask = mask;
+	m_descriptor = -1;
+    }
+
+    protected void finalize() {
+	stopWatching();
+    }
+
+    public void startWatching() {
+	if (m_descriptor < 0) {
+	    m_descriptor = s_observerThread.startWatching(m_path, m_mask, this);
+	}
+    }
+
+    public void stopWatching() {
+	if (m_descriptor >= 0) {
+	    s_observerThread.stopWatching(m_descriptor);
+	    m_descriptor = -1;
+	}
+    }
+
+    public abstract void onEvent(int event, String path);
+}
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
new file mode 100644
index 0000000..51dfb5b
--- /dev/null
+++ b/core/java/android/os/FileUtils.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2006 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 java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.regex.Pattern;
+
+
+/**
+ * Tools for managing files.  Not for public consumption.
+ * @hide
+ */
+public class FileUtils
+{
+    public static final int S_IRWXU = 00700;
+    public static final int S_IRUSR = 00400;
+    public static final int S_IWUSR = 00200;
+    public static final int S_IXUSR = 00100;
+
+    public static final int S_IRWXG = 00070;
+    public static final int S_IRGRP = 00040;
+    public static final int S_IWGRP = 00020;
+    public static final int S_IXGRP = 00010;
+
+    public static final int S_IRWXO = 00007;
+    public static final int S_IROTH = 00004;
+    public static final int S_IWOTH = 00002;
+    public static final int S_IXOTH = 00001;
+    
+    
+    /**
+     * File status information. This class maps directly to the POSIX stat structure.
+     * @hide
+     */
+    public static final class FileStatus {
+        public int dev;
+        public int ino;
+        public int mode;
+        public int nlink;
+        public int uid;
+        public int gid;
+        public int rdev;
+        public long size;
+        public int blksize;
+        public long blocks;
+        public long atime;
+        public long mtime;
+        public long ctime;
+    }
+    
+    /**
+     * Get the status for the given path. This is equivalent to the POSIX stat(2) system call. 
+     * @param path The path of the file to be stat'd.
+     * @param status Optional argument to fill in. It will only fill in the status if the file
+     * exists. 
+     * @return true if the file exists and false if it does not exist. If you do not have 
+     * permission to stat the file, then this method will return false.
+     */
+    public static native boolean getFileStatus(String path, FileStatus status);
+
+    /** Regular expression for safe filenames: no spaces or metacharacters */
+    private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+");
+
+    public static native int setPermissions(String file, int mode, int uid, int gid);
+
+    public static native int getPermissions(String file, int[] outPermissions);
+
+    /** returns the FAT file system volume ID for the volume mounted 
+     * at the given mount point, or -1 for failure
+     * @param mount point for FAT volume
+     * @return volume ID or -1
+     */
+    public static native int getFatVolumeId(String mountPoint);
+        
+    // copy a file from srcFile to destFile, return true if succeed, return
+    // false if fail
+    public static boolean copyFile(File srcFile, File destFile) {
+        boolean result = false;
+        try {
+            InputStream in = new FileInputStream(srcFile);
+            try {
+                result = copyToFile(in, destFile);
+            } finally  {
+                in.close();
+            }
+        } catch (IOException e) {
+            result = false;
+        }
+        return result;
+    }
+    
+    /**
+     * Copy data from a source stream to destFile.
+     * Return true if succeed, return false if failed.
+     */
+    public static boolean copyToFile(InputStream inputStream, File destFile) {
+        try {
+            OutputStream out = new FileOutputStream(destFile);
+            try {
+                byte[] buffer = new byte[4096];
+                int bytesRead;
+                while ((bytesRead = inputStream.read(buffer)) >= 0) {
+                    out.write(buffer, 0, bytesRead);
+                }
+            } finally {
+                out.close();
+            }
+            return true;
+        } catch (IOException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Check if a filename is "safe" (no metacharacters or spaces).
+     * @param file  The file to check
+     */
+    public static boolean isFilenameSafe(File file) {
+        // Note, we check whether it matches what's known to be safe,
+        // rather than what's known to be unsafe.  Non-ASCII, control
+        // characters, etc. are all unsafe by default.
+        return SAFE_FILENAME_PATTERN.matcher(file.getPath()).matches();
+    }
+
+    /**
+     * Read a text file into a String, optionally limiting the length.
+     * @param file to read (will not seek, so things like /proc files are OK)
+     * @param max length (positive for head, negative of tail, 0 for no limit)
+     * @param ellipsis to add of the file was truncated (can be null)
+     * @return the contents of the file, possibly truncated
+     * @throws IOException if something goes wrong reading the file
+     */
+    public static String readTextFile(File file, int max, String ellipsis) throws IOException {
+        InputStream input = new FileInputStream(file);
+        try {
+            if (max > 0) {  // "head" mode: read the first N bytes
+                byte[] data = new byte[max + 1];
+                int length = input.read(data);
+                if (length <= 0) return "";
+                if (length <= max) return new String(data, 0, length);
+                if (ellipsis == null) return new String(data, 0, max);
+                return new String(data, 0, max) + ellipsis;
+            } else if (max < 0) {  // "tail" mode: read it all, keep the last N
+                int len;
+                boolean rolled = false;
+                byte[] last = null, data = null;
+                do {
+                    if (last != null) rolled = true;
+                    byte[] tmp = last; last = data; data = tmp;
+                    if (data == null) data = new byte[-max];
+                    len = input.read(data);
+                } while (len == data.length);
+
+                if (last == null && len <= 0) return "";
+                if (last == null) return new String(data, 0, len);
+                if (len > 0) {
+                    rolled = true;
+                    System.arraycopy(last, len, last, 0, last.length - len);
+                    System.arraycopy(data, 0, last, last.length - len, len);
+                }
+                if (ellipsis == null || !rolled) return new String(last);
+                return ellipsis + new String(last);
+            } else {  // "cat" mode: read it all
+                ByteArrayOutputStream contents = new ByteArrayOutputStream();
+                int len;
+                byte[] data = new byte[1024];
+                do {
+                    len = input.read(data);
+                    if (len > 0) contents.write(data, 0, len);
+                } while (len == data.length);
+                return contents.toString();
+            }
+        } finally {
+            input.close();
+        }
+    }
+}
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
new file mode 100644
index 0000000..2a32e54
--- /dev/null
+++ b/core/java/android/os/Handler.java
@@ -0,0 +1,594 @@
+/*
+ * Copyright (C) 2006 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 android.util.Printer;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * A Handler allows you to send and process {@link Message} and Runnable
+ * objects associated with a thread's {@link MessageQueue}.  Each Handler
+ * instance is associated with a single thread and that thread's message
+ * queue.  When you create a new Handler, it is bound to the thread /
+ * message queue of the thread that is creating it -- from that point on,
+ * it will deliver messages and runnables to that message queue and execute
+ * them as they come out of the message queue.
+ * 
+ * <p>There are two main uses for a Handler: (1) to schedule messages and
+ * runnables to be executed as some point in the future; and (2) to enqueue
+ * an action to be performed on a different thread than your own.
+ * 
+ * <p>Scheduling messages is accomplished with the
+ * {@link #post}, {@link #postAtTime(Runnable, long)},
+ * {@link #postDelayed}, {@link #sendEmptyMessage},
+ * {@link #sendMessage}, {@link #sendMessageAtTime}, and
+ * {@link #sendMessageDelayed} methods.  The <em>post</em> versions allow
+ * you to enqueue Runnable objects to be called by the message queue when
+ * they are received; the <em>sendMessage</em> versions allow you to enqueue
+ * a {@link Message} object containing a bundle of data that will be
+ * processed by the Handler's {@link #handleMessage} method (requiring that
+ * you implement a subclass of Handler).
+ * 
+ * <p>When posting or sending to a Handler, you can either
+ * allow the item to be processed as soon as the message queue is ready
+ * to do so, or specify a delay before it gets processed or absolute time for
+ * it to be processed.  The latter two allow you to implement timeouts,
+ * ticks, and other timing-based behavior.
+ * 
+ * <p>When a
+ * process is created for your application, its main thread is dedicated to
+ * running a message queue that takes care of managing the top-level
+ * application objects (activities, broadcast receivers, etc) and any windows
+ * they create.  You can create your own threads, and communicate back with
+ * the main application thread through a Handler.  This is done by calling
+ * the same <em>post</em> or <em>sendMessage</em> methods as before, but from
+ * your new thread.  The given Runnable or Message will than be scheduled
+ * in the Handler's message queue and processed when appropriate.
+ */
+public class Handler {
+    /*
+     * Set this flag to true to detect anonymous, local or member classes
+     * that extend this Handler class and that are not static. These kind
+     * of classes can potentially create leaks.
+     */
+    private static final boolean FIND_POTENTIAL_LEAKS = false;
+    private static final String TAG = "Handler";
+
+    /**
+     * Callback interface you can use when instantiating a Handler to avoid
+     * having to implement your own subclass of Handler.
+     */
+    public interface Callback {
+        public boolean handleMessage(Message msg);
+    }
+    
+    /**
+     * Subclasses must implement this to receive messages.
+     */
+    public void handleMessage(Message msg) {
+    }
+    
+    /**
+     * Handle system messages here.
+     */
+    public void dispatchMessage(Message msg) {
+        if (msg.callback != null) {
+            handleCallback(msg);
+        } else {
+            if (mCallback != null) {
+                if (mCallback.handleMessage(msg)) {
+                    return;
+                }
+            }
+            handleMessage(msg);
+        }
+    }
+
+    /**
+     * Default constructor associates this handler with the queue for the
+     * current thread.
+     *
+     * If there isn't one, this handler won't be able to receive messages.
+     */
+    public Handler() {
+        if (FIND_POTENTIAL_LEAKS) {
+            final Class<? extends Handler> klass = getClass();
+            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
+                    (klass.getModifiers() & Modifier.STATIC) == 0) {
+                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
+                    klass.getCanonicalName());
+            }
+        }
+
+        mLooper = Looper.myLooper();
+        if (mLooper == null) {
+            throw new RuntimeException(
+                "Can't create handler inside thread that has not called Looper.prepare()");
+        }
+        mQueue = mLooper.mQueue;
+        mCallback = null;
+    }
+
+    /**
+     * Constructor associates this handler with the queue for the
+     * current thread and takes a callback interface in which you can handle
+     * messages.
+     */
+    public Handler(Callback callback) {
+        if (FIND_POTENTIAL_LEAKS) {
+            final Class<? extends Handler> klass = getClass();
+            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
+                    (klass.getModifiers() & Modifier.STATIC) == 0) {
+                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
+                    klass.getCanonicalName());
+            }
+        }
+
+        mLooper = Looper.myLooper();
+        if (mLooper == null) {
+            throw new RuntimeException(
+                "Can't create handler inside thread that has not called Looper.prepare()");
+        }
+        mQueue = mLooper.mQueue;
+        mCallback = callback;
+    }
+
+    /**
+     * Use the provided queue instead of the default one.
+     */
+    public Handler(Looper looper) {
+        mLooper = looper;
+        mQueue = looper.mQueue;
+        mCallback = null;
+    }
+
+    /**
+     * Use the provided queue instead of the default one and take a callback
+     * interface in which to handle messages.
+     */
+    public Handler(Looper looper, Callback callback) {
+        mLooper = looper;
+        mQueue = looper.mQueue;
+        mCallback = callback;
+    }
+
+    /**
+     * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
+     * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
+     *  If you don't want that facility, just call Message.obtain() instead.
+     */
+    public final Message obtainMessage()
+    {
+        return Message.obtain(this);
+    }
+
+    /**
+     * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message.
+     * 
+     * @param what Value to assign to the returned Message.what field.
+     * @return A Message from the global message pool.
+     */
+    public final Message obtainMessage(int what)
+    {
+        return Message.obtain(this, what);
+    }
+    
+    /**
+     * 
+     * Same as {@link #obtainMessage()}, except that it also sets the what and obj members 
+     * of the returned Message.
+     * 
+     * @param what Value to assign to the returned Message.what field.
+     * @param obj Value to assign to the returned Message.obj field.
+     * @return A Message from the global message pool.
+     */
+    public final Message obtainMessage(int what, Object obj)
+    {
+        return Message.obtain(this, what, obj);
+    }
+
+    /**
+     * 
+     * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned
+     * Message.
+     * @param what Value to assign to the returned Message.what field.
+     * @param arg1 Value to assign to the returned Message.arg1 field.
+     * @param arg2 Value to assign to the returned Message.arg2 field.
+     * @return A Message from the global message pool.
+     */
+    public final Message obtainMessage(int what, int arg1, int arg2)
+    {
+        return Message.obtain(this, what, arg1, arg2);
+    }
+    
+    /**
+     * 
+     * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the 
+     * returned Message.
+     * @param what Value to assign to the returned Message.what field.
+     * @param arg1 Value to assign to the returned Message.arg1 field.
+     * @param arg2 Value to assign to the returned Message.arg2 field.
+     * @param obj Value to assign to the returned Message.obj field.
+     * @return A Message from the global message pool.
+     */
+    public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
+    {
+        return Message.obtain(this, what, arg1, arg2, obj);
+    }
+
+    /**
+     * Causes the Runnable r to be added to the message queue.
+     * The runnable will be run on the thread to which this handler is 
+     * attached. 
+     *  
+     * @param r The Runnable that will be executed.
+     * 
+     * @return Returns true if the Runnable was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.
+     */
+    public final boolean post(Runnable r)
+    {
+       return  sendMessageDelayed(getPostMessage(r), 0);
+    }
+    
+    /**
+     * Causes the Runnable r to be added to the message queue, to be run
+     * at a specific time given by <var>uptimeMillis</var>.
+     * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
+     * The runnable will be run on the thread to which this handler is attached.
+     *
+     * @param r The Runnable that will be executed.
+     * @param uptimeMillis The absolute time at which the callback should run,
+     *         using the {@link android.os.SystemClock#uptimeMillis} time-base.
+     *  
+     * @return Returns true if the Runnable was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.  Note that a
+     *         result of true does not mean the Runnable will be processed -- if
+     *         the looper is quit before the delivery time of the message
+     *         occurs then the message will be dropped.
+     */
+    public final boolean postAtTime(Runnable r, long uptimeMillis)
+    {
+        return sendMessageAtTime(getPostMessage(r), uptimeMillis);
+    }
+    
+    /**
+     * Causes the Runnable r to be added to the message queue, to be run
+     * at a specific time given by <var>uptimeMillis</var>.
+     * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
+     * The runnable will be run on the thread to which this handler is attached.
+     *
+     * @param r The Runnable that will be executed.
+     * @param uptimeMillis The absolute time at which the callback should run,
+     *         using the {@link android.os.SystemClock#uptimeMillis} time-base.
+     * 
+     * @return Returns true if the Runnable was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.  Note that a
+     *         result of true does not mean the Runnable will be processed -- if
+     *         the looper is quit before the delivery time of the message
+     *         occurs then the message will be dropped.
+     *         
+     * @see android.os.SystemClock#uptimeMillis
+     */
+    public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
+    {
+        return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
+    }
+    
+    /**
+     * Causes the Runnable r to be added to the message queue, to be run
+     * after the specified amount of time elapses.
+     * The runnable will be run on the thread to which this handler
+     * is attached.
+     *  
+     * @param r The Runnable that will be executed.
+     * @param delayMillis The delay (in milliseconds) until the Runnable
+     *        will be executed.
+     *        
+     * @return Returns true if the Runnable was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.  Note that a
+     *         result of true does not mean the Runnable will be processed --
+     *         if the looper is quit before the delivery time of the message
+     *         occurs then the message will be dropped.
+     */
+    public final boolean postDelayed(Runnable r, long delayMillis)
+    {
+        return sendMessageDelayed(getPostMessage(r), delayMillis);
+    }
+    
+    /**
+     * Posts a message to an object that implements Runnable.
+     * Causes the Runnable r to executed on the next iteration through the
+     * message queue. The runnable will be run on the thread to which this
+     * handler is attached.
+     * <b>This method is only for use in very special circumstances -- it
+     * can easily starve the message queue, cause ordering problems, or have
+     * other unexpected side-effects.</b>
+     *  
+     * @param r The Runnable that will be executed.
+     * 
+     * @return Returns true if the message was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.
+     */
+    public final boolean postAtFrontOfQueue(Runnable r)
+    {
+        return sendMessageAtFrontOfQueue(getPostMessage(r));
+    }
+
+    /**
+     * Remove any pending posts of Runnable r that are in the message queue.
+     */
+    public final void removeCallbacks(Runnable r)
+    {
+        mQueue.removeMessages(this, r, null);
+    }
+
+    /**
+     * Remove any pending posts of Runnable <var>r</var> with Object
+     * <var>token</var> that are in the message queue.
+     */
+    public final void removeCallbacks(Runnable r, Object token)
+    {
+        mQueue.removeMessages(this, r, token);
+    }
+
+    /**
+     * Pushes a message onto the end of the message queue after all pending messages
+     * before the current time. It will be received in {@link #handleMessage},
+     * in the thread attached to this handler.
+     *  
+     * @return Returns true if the message was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.
+     */
+    public final boolean sendMessage(Message msg)
+    {
+        return sendMessageDelayed(msg, 0);
+    }
+
+    /**
+     * Sends a Message containing only the what value.
+     *  
+     * @return Returns true if the message was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.
+     */
+    public final boolean sendEmptyMessage(int what)
+    {
+        return sendEmptyMessageDelayed(what, 0);
+    }
+
+    /**
+     * Sends a Message containing only the what value, to be delivered
+     * after the specified amount of time elapses.
+     * @see #sendMessageDelayed(android.os.Message, long) 
+     * 
+     * @return Returns true if the message was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.
+     */
+    public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
+        Message msg = Message.obtain();
+        msg.what = what;
+        return sendMessageDelayed(msg, delayMillis);
+    }
+
+    /**
+     * Sends a Message containing only the what value, to be delivered 
+     * at a specific time.
+     * @see #sendMessageAtTime(android.os.Message, long)
+     *  
+     * @return Returns true if the message was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.
+     */
+
+    public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
+        Message msg = Message.obtain();
+        msg.what = what;
+        return sendMessageAtTime(msg, uptimeMillis);
+    }
+
+    /**
+     * Enqueue a message into the message queue after all pending messages
+     * before (current time + delayMillis). You will receive it in
+     * {@link #handleMessage}, in the thread attached to this handler.
+     *  
+     * @return Returns true if the message was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.  Note that a
+     *         result of true does not mean the message will be processed -- if
+     *         the looper is quit before the delivery time of the message
+     *         occurs then the message will be dropped.
+     */
+    public final boolean sendMessageDelayed(Message msg, long delayMillis)
+    {
+        if (delayMillis < 0) {
+            delayMillis = 0;
+        }
+        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
+    }
+
+    /**
+     * Enqueue a message into the message queue after all pending messages
+     * before the absolute time (in milliseconds) <var>uptimeMillis</var>.
+     * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
+     * You will receive it in {@link #handleMessage}, in the thread attached
+     * to this handler.
+     * 
+     * @param uptimeMillis The absolute time at which the message should be
+     *         delivered, using the
+     *         {@link android.os.SystemClock#uptimeMillis} time-base.
+     *         
+     * @return Returns true if the message was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.  Note that a
+     *         result of true does not mean the message will be processed -- if
+     *         the looper is quit before the delivery time of the message
+     *         occurs then the message will be dropped.
+     */
+    public boolean sendMessageAtTime(Message msg, long uptimeMillis)
+    {
+        boolean sent = false;
+        MessageQueue queue = mQueue;
+        if (queue != null) {
+            msg.target = this;
+            sent = queue.enqueueMessage(msg, uptimeMillis);
+        }
+        else {
+            RuntimeException e = new RuntimeException(
+                this + " sendMessageAtTime() called with no mQueue");
+            Log.w("Looper", e.getMessage(), e);
+        }
+        return sent;
+    }
+
+    /**
+     * Enqueue a message at the front of the message queue, to be processed on
+     * the next iteration of the message loop.  You will receive it in
+     * {@link #handleMessage}, in the thread attached to this handler.
+     * <b>This method is only for use in very special circumstances -- it
+     * can easily starve the message queue, cause ordering problems, or have
+     * other unexpected side-effects.</b>
+     *  
+     * @return Returns true if the message was successfully placed in to the 
+     *         message queue.  Returns false on failure, usually because the
+     *         looper processing the message queue is exiting.
+     */
+    public final boolean sendMessageAtFrontOfQueue(Message msg)
+    {
+        boolean sent = false;
+        MessageQueue queue = mQueue;
+        if (queue != null) {
+            msg.target = this;
+            sent = queue.enqueueMessage(msg, 0);
+        }
+        else {
+            RuntimeException e = new RuntimeException(
+                this + " sendMessageAtTime() called with no mQueue");
+            Log.w("Looper", e.getMessage(), e);
+        }
+        return sent;
+    }
+
+    /**
+     * Remove any pending posts of messages with code 'what' that are in the
+     * message queue.
+     */
+    public final void removeMessages(int what) {
+        mQueue.removeMessages(this, what, null, true);
+    }
+
+    /**
+     * Remove any pending posts of messages with code 'what' and whose obj is
+     * 'object' that are in the message queue.
+     */
+    public final void removeMessages(int what, Object object) {
+        mQueue.removeMessages(this, what, object, true);
+    }
+
+    /**
+     * Remove any pending posts of callbacks and sent messages whose
+     * <var>obj</var> is <var>token</var>.
+     */
+    public final void removeCallbacksAndMessages(Object token) {
+        mQueue.removeCallbacksAndMessages(this, token);
+    }
+
+    /**
+     * Check if there are any pending posts of messages with code 'what' in
+     * the message queue.
+     */
+    public final boolean hasMessages(int what) {
+        return mQueue.removeMessages(this, what, null, false);
+    }
+
+    /**
+     * Check if there are any pending posts of messages with code 'what' and
+     * whose obj is 'object' in the message queue.
+     */
+    public final boolean hasMessages(int what, Object object) {
+        return mQueue.removeMessages(this, what, object, false);
+    }
+
+    // if we can get rid of this method, the handler need not remember its loop
+    // we could instead export a getMessageQueue() method... 
+    public final Looper getLooper() {
+        return mLooper;
+    }
+
+    public final void dump(Printer pw, String prefix) {
+        pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
+        if (mLooper == null) {
+            pw.println(prefix + "looper uninitialized");
+        } else {
+            mLooper.dump(pw, prefix + "  ");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Handler{"
+        + Integer.toHexString(System.identityHashCode(this))
+        + "}";
+    }
+
+    final IMessenger getIMessenger() {
+        synchronized (mQueue) {
+            if (mMessenger != null) {
+                return mMessenger;
+            }
+            mMessenger = new MessengerImpl();
+            return mMessenger;
+        }
+    }
+    
+    private final class MessengerImpl extends IMessenger.Stub {
+        public void send(Message msg) {
+            Handler.this.sendMessage(msg);
+        }
+    }
+    
+    private final Message getPostMessage(Runnable r) {
+        Message m = Message.obtain();
+        m.callback = r;
+        return m;
+    }
+
+    private final Message getPostMessage(Runnable r, Object token) {
+        Message m = Message.obtain();
+        m.obj = token;
+        m.callback = r;
+        return m;
+    }
+
+    private final void handleCallback(Message message) {
+        message.callback.run();
+    }
+
+    final MessageQueue mQueue;
+    final Looper mLooper;
+    final Callback mCallback;
+    IMessenger mMessenger;
+}
diff --git a/core/java/android/os/HandlerState.java b/core/java/android/os/HandlerState.java
new file mode 100644
index 0000000..0708f7d
--- /dev/null
+++ b/core/java/android/os/HandlerState.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * {@hide}
+ */
+public abstract class HandlerState {
+    public HandlerState() {
+    }
+
+    public void enter(Message message) {
+    }
+
+    public abstract void processMessage(Message message);
+
+    public void exit(Message message) {
+    }
+}
diff --git a/core/java/android/os/HandlerStateMachine.java b/core/java/android/os/HandlerStateMachine.java
new file mode 100644
index 0000000..d004a25
--- /dev/null
+++ b/core/java/android/os/HandlerStateMachine.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2006 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 android.util.LogPrinter;
+
+/**
+ * {@hide}
+ *
+ * Implement a state machine where each state is an object,
+ * HandlerState. Each HandlerState must implement processMessage
+ * and optionally enter/exit. When a state machine is created
+ * the initial state must be set. When messages are sent to
+ * a state machine the current state's processMessage method is
+ * invoked. If this is the first message for this state the
+ * enter method is called prior to processMessage and when
+ * transtionTo is invoked the state's exit method will be
+ * called after returning from processMessage.
+ *
+ * If a message should be handled in a different state the
+ * processMessage method may call deferMessage. This causes
+ * the message to be saved on a list until transitioning
+ * to a new state, at which time all of the deferred messages
+ * will be put on the front of the state machines queue and
+ * processed by the new current state's processMessage
+ * method.
+ *
+ * Below is an example state machine with two state's, S1 and S2.
+ * The initial state is S1 which defers all messages and only
+ * transition to S2 when message.what == TEST_WHAT_2. State S2
+ * will process each messages until it receives TEST_WHAT_2
+ * where it will transition back to S1:
+<code>
+     class StateMachine1 extends HandlerStateMachine {
+        private static final int TEST_WHAT_1 = 1;
+        private static final int TEST_WHAT_2 = 2;
+
+        StateMachine1(String name) {
+            super(name);
+            setInitialState(mS1);
+        }
+
+        class S1 extends HandlerState {
+            @Override public void enter(Message message) {
+            }
+
+            @Override public void processMessage(Message message) {
+                deferMessage(message);
+                if (message.what == TEST_WHAT_2) {
+                    transitionTo(mS2);
+                }
+            }
+
+            @Override public void exit(Message message) {
+            }
+        }
+
+        class S2 extends HandlerState {
+            @Override public void processMessage(Message message) {
+                // Do some processing
+                if (message.what == TEST_WHAT_2) {
+                    transtionTo(mS1);
+                }
+            }
+        }
+
+        private S1 mS1 = new S1();
+        private S2 mS2 = new S2();
+    }
+</code>
+ */
+public class HandlerStateMachine {
+
+    private boolean mDbg = false;
+    private static final String TAG = "HandlerStateMachine";
+    private String mName;
+    private SmHandler mHandler;
+    private HandlerThread mHandlerThread;
+
+    /**
+     * Handle messages sent to the state machine by calling
+     * the current state's processMessage. It also handles
+     * the enter/exit calls and placing any deferred messages
+     * back onto the queue when transitioning to a new state.
+     */
+    class SmHandler extends Handler {
+
+        SmHandler(Looper looper) {
+          super(looper);
+        }
+
+        /**
+         * This will dispatch the message to the
+         * current state's processMessage.
+         */
+        @Override
+        final public void handleMessage(Message msg) {
+            if (mDbg) Log.d(TAG, "SmHandler.handleMessage E");
+            if (mDestState != null) {
+                if (mDbg) Log.d(TAG, "SmHandler.handleMessage; new destation call enter");
+                mCurrentState = mDestState;
+                mDestState = null;
+                mCurrentState.enter(msg);
+            }
+            if (mCurrentState != null) {
+                if (mDbg) Log.d(TAG, "SmHandler.handleMessage; call processMessage");
+                mCurrentState.processMessage(msg);
+            } else {
+                /* Strange no state to execute */
+                Log.e(TAG, "handleMessage: no current state, did you call setInitialState");
+            }
+
+            if (mDestState != null) {
+                if (mDbg) Log.d(TAG, "SmHandler.handleMessage; new destination call exit");
+                mCurrentState.exit(msg);
+
+                /**
+                 * Place the messages from the deferred queue:t
+                 * on to the Handler's message queue in the
+                 * same order that they originally arrived.
+                 *
+                 * We set cur.when = 0 to circumvent the check
+                 * that this message has already been sent.
+                 */
+                while (mDeferredMessages != null) {
+                    Message cur = mDeferredMessages;
+                    mDeferredMessages = mDeferredMessages.next;
+                    cur.when = 0;
+                    if (mDbg) Log.d(TAG, "SmHandler.handleMessage; queue deferred message what="
+                                                + cur.what + " target=" + cur.target);
+                    sendMessageAtFrontOfQueue(cur);
+                }
+                if (mDbg) Log.d(TAG, "SmHandler.handleMessage X");
+            }
+        }
+
+        public HandlerState mCurrentState;
+        public HandlerState mDestState;
+        public Message mDeferredMessages;
+    }
+
+    /**
+     * Create an active StateMachine, one that has a
+     * dedicated thread/looper/queue.
+     */
+    public HandlerStateMachine(String name) {
+        mName = name;
+        mHandlerThread =  new HandlerThread(name);
+        mHandlerThread.start();
+        mHandler = new SmHandler(mHandlerThread.getLooper());
+    }
+
+    /**
+     * Get a message and set Message.target = this.
+     */
+    public final Message obtainMessage()
+    {
+        Message msg = Message.obtain(mHandler);
+        if (mDbg) Log.d(TAG, "StateMachine.obtainMessage() EX target=" + msg.target);
+        return msg;
+    }
+
+    /**
+     * Get a message and set Message.target = this and
+     * Message.what = what.
+     */
+    public final Message obtainMessage(int what) {
+        Message msg = Message.obtain(mHandler, what);
+        if (mDbg) {
+            Log.d(TAG, "StateMachine.obtainMessage(what) EX what=" + msg.what +
+                       " target=" + msg.target);
+        }
+        return msg;
+    }
+
+    /**
+     * Enqueue a message to this state machine.
+     */
+    public final void sendMessage(Message msg) {
+        if (mDbg) Log.d(TAG, "StateMachine.sendMessage EX msg.what=" + msg.what);
+        mHandler.sendMessage(msg);
+    }
+
+    /**
+     * Enqueue a message to this state machine after a delay.
+     */
+    public final void sendMessageDelayed(Message msg, long delayMillis) {
+        if (mDbg) {
+            Log.d(TAG, "StateMachine.sendMessageDelayed EX msg.what="
+                            + msg.what + " delay=" + delayMillis);
+        }
+        mHandler.sendMessageDelayed(msg, delayMillis);
+    }
+
+    /**
+     * Set the initial state. This must be invoked before
+     * and messages are sent to the state machine.
+     */
+    public void setInitialState(HandlerState initialState) {
+        if (mDbg) {
+            Log.d(TAG, "StateMachine.setInitialState EX initialState"
+                            + initialState.getClass().getName());
+        }
+        mHandler.mDestState = initialState;
+    }
+
+    /**
+     * transition to destination state. Upon returning
+     * from processMessage the current state's exit will
+     * be executed and upon the next message arriving
+     * destState.enter will be invoked.
+     */
+    final public void transitionTo(HandlerState destState) {
+        if (mDbg) {
+            Log.d(TAG, "StateMachine.transitionTo EX destState"
+                            + destState.getClass().getName());
+        }
+        mHandler.mDestState = destState;
+    }
+
+    /**
+     * Defer this message until next state transition.
+     * Upon transitioning all deferred messages will be
+     * placed on the queue and reprocessed in the original
+     * order. (i.e. The next state the oldest messages will
+     * be processed first)
+     */
+    final public void deferMessage(Message msg) {
+        if (mDbg) {
+            Log.d(TAG, "StateMachine.deferMessage EX mDeferredMessages="
+                            + mHandler.mDeferredMessages);
+        }
+
+        /* Copy the "msg" to "newMsg" as "msg" will be recycled */
+        Message newMsg = obtainMessage();
+        newMsg.copyFrom(msg);
+
+        /* Place on front of queue */
+        newMsg.next = mHandler.mDeferredMessages;
+        mHandler.mDeferredMessages = newMsg;
+    }
+
+    /**
+     * @return the name
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * @return Handler
+     */
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    /**
+     * @return if debugging is enabled
+     */
+    public boolean isDbg() {
+        return mDbg;
+    }
+
+    /**
+     * Set debug enable/disabled.
+     */
+    public void setDbg(boolean dbg) {
+        mDbg = dbg;
+        if (mDbg) {
+            mHandlerThread.getLooper().setMessageLogging(new LogPrinter(Log.VERBOSE, TAG));
+        } else {
+            mHandlerThread.getLooper().setMessageLogging(null);
+        }
+   }
+}
diff --git a/core/java/android/os/HandlerThread.java b/core/java/android/os/HandlerThread.java
new file mode 100644
index 0000000..0ce86db
--- /dev/null
+++ b/core/java/android/os/HandlerThread.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * Handy class for starting a new thread that has a looper. The looper can then be 
+ * used to create handler classes. Note that start() must still be called.
+ */
+public class HandlerThread extends Thread {
+    private int mPriority;
+    private int mTid = -1;
+    private Looper mLooper;
+
+    public HandlerThread(String name) {
+        super(name);
+        mPriority = Process.THREAD_PRIORITY_DEFAULT;
+    }
+    
+    /**
+     * Constructs a HandlerThread.
+     * @param name
+     * @param priority The priority to run the thread at. The value supplied must be from 
+     * {@link android.os.Process} and not from java.lang.Thread.
+     */
+    public HandlerThread(String name, int priority) {
+        super(name);
+        mPriority = priority;
+    }
+    
+    /**
+     * Call back method that can be explicitly over ridden if needed to execute some
+     * setup before Looper loops.
+     */
+    protected void onLooperPrepared() {
+    }
+
+    public void run() {
+        mTid = Process.myTid();
+        Looper.prepare();
+        synchronized (this) {
+            mLooper = Looper.myLooper();
+            Process.setThreadPriority(mPriority);
+            notifyAll();
+        }
+        onLooperPrepared();
+        Looper.loop();
+        mTid = -1;
+    }
+    
+    /**
+     * This method returns the Looper associated with this thread. If this thread not been started
+     * or for any reason is isAlive() returns false, this method will return null. If this thread 
+     * has been started, this method will blocked until the looper has been initialized.  
+     * @return The looper.
+     */
+    public Looper getLooper() {
+        if (!isAlive()) {
+            return null;
+        }
+        
+        // If the thread has been started, wait until the looper has been created.
+        synchronized (this) {
+            while (isAlive() && mLooper == null) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+        return mLooper;
+    }
+    
+    /**
+     * Returns the identifier of this thread. See Process.myTid().
+     */
+    public int getThreadId() {
+        return mTid;
+    }
+}
diff --git a/core/java/android/os/Hardware.java b/core/java/android/os/Hardware.java
new file mode 100644
index 0000000..3b6c9d7
--- /dev/null
+++ b/core/java/android/os/Hardware.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * {@hide}
+ */
+public class Hardware 
+{
+    /**
+     * Control the LED.
+     */
+    public static native int setLedState(int colorARGB, int onMS, int offMS);
+    
+    /**
+     * Control the Flashlight
+     */
+    public static native boolean getFlashlightEnabled();
+    public static native void setFlashlightEnabled(boolean on);
+    public static native void enableCameraFlash(int milliseconds);
+
+    /**
+     * Control the backlights
+     */
+    public static native void setScreenBacklight(int brightness);
+    public static native void setKeyboardBacklight(boolean on);
+    public static native void setButtonBacklight(boolean on);
+}
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
new file mode 100644
index 0000000..5c40c9a0
--- /dev/null
+++ b/core/java/android/os/IBinder.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2006 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 java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Base interface for a remotable object, the core part of a lightweight
+ * remote procedure call mechanism designed for high performance when
+ * performing in-process and cross-process calls.  This
+ * interface describes the abstract protocol for interacting with a
+ * remotable object.  Do not implement this interface directly, instead
+ * extend from {@link Binder}.
+ * 
+ * <p>The key IBinder API is {@link #transact transact()} matched by
+ * {@link Binder#onTransact Binder.onTransact()}.  These
+ * methods allow you to send a call to an IBinder object and receive a
+ * call coming in to a Binder object, respectively.  This transaction API
+ * is synchronous, such that a call to {@link #transact transact()} does not
+ * return until the target has returned from
+ * {@link Binder#onTransact Binder.onTransact()}; this is the
+ * expected behavior when calling an object that exists in the local
+ * process, and the underlying inter-process communication (IPC) mechanism
+ * ensures that these same semantics apply when going across processes.
+ * 
+ * <p>The data sent through transact() is a {@link Parcel}, a generic buffer
+ * of data that also maintains some meta-data about its contents.  The meta
+ * data is used to manage IBinder object references in the buffer, so that those
+ * references can be maintained as the buffer moves across processes.  This
+ * mechanism ensures that when an IBinder is written into a Parcel and sent to
+ * another process, if that other process sends a reference to that same IBinder
+ * back to the original process, then the original process will receive the
+ * same IBinder object back.  These semantics allow IBinder/Binder objects to
+ * be used as a unique identity (to serve as a token or for other purposes)
+ * that can be managed across processes.
+ * 
+ * <p>The system maintains a pool of transaction threads in each process that
+ * it runs in.  These threads are used to dispatch all
+ * IPCs coming in from other processes.  For example, when an IPC is made from
+ * process A to process B, the calling thread in A blocks in transact() as
+ * it sends the transaction to process B.  The next available pool thread in
+ * B receives the incoming transaction, calls Binder.onTransact() on the target
+ * object, and replies with the result Parcel.  Upon receiving its result, the
+ * thread in process A returns to allow its execution to continue.  In effect,
+ * other processes appear to use as additional threads that you did not create
+ * executing in your own process.
+ * 
+ * <p>The Binder system also supports recursion across processes.  For example
+ * if process A performs a transaction to process B, and process B while
+ * handling that transaction calls transact() on an IBinder that is implemented
+ * in A, then the thread in A that is currently waiting for the original
+ * transaction to finish will take care of calling Binder.onTransact() on the
+ * object being called by B.  This ensures that the recursion semantics when
+ * calling remote binder object are the same as when calling local objects.
+ * 
+ * <p>When working with remote objects, you often want to find out when they
+ * are no longer valid.  There are three ways this can be determined:
+ * <ul>
+ * <li> The {@link #transact transact()} method will throw a
+ * {@link RemoteException} exception if you try to call it on an IBinder
+ * whose process no longer exists.
+ * <li> The {@link #pingBinder()} method can be called, and will return false
+ * if the remote process no longer exists.
+ * <li> The {@link #linkToDeath linkToDeath()} method can be used to register
+ * a {@link DeathRecipient} with the IBinder, which will be called when its
+ * containing process goes away.
+ * </ul>
+ * 
+ * @see Binder
+ */
+public interface IBinder {
+    /**
+     * The first transaction code available for user commands.
+     */
+    int FIRST_CALL_TRANSACTION  = 0x00000001;
+    /**
+     * The last transaction code available for user commands.
+     */
+    int LAST_CALL_TRANSACTION   = 0x00ffffff;
+    
+    /**
+     * IBinder protocol transaction code: pingBinder().
+     */
+    int PING_TRANSACTION        = ('_'<<24)|('P'<<16)|('N'<<8)|'G';
+    
+    /**
+     * IBinder protocol transaction code: dump internal state.
+     */
+    int DUMP_TRANSACTION        = ('_'<<24)|('D'<<16)|('M'<<8)|'P';
+    
+    /**
+     * IBinder protocol transaction code: interrogate the recipient side
+     * of the transaction for its canonical interface descriptor.
+     */
+    int INTERFACE_TRANSACTION   = ('_'<<24)|('N'<<16)|('T'<<8)|'F';
+
+    /**
+     * Flag to {@link #transact}: this is a one-way call, meaning that the
+     * caller returns immediately, without waiting for a result from the
+     * callee.
+     */
+    int FLAG_ONEWAY             = 0x00000001;
+    
+    /**
+     * Get the canonical name of the interface supported by this binder.
+     */
+    public String getInterfaceDescriptor() throws RemoteException;
+
+    /**
+     * Check to see if the object still exists.
+     * 
+     * @return Returns false if the
+     * hosting process is gone, otherwise the result (always by default
+     * true) returned by the pingBinder() implementation on the other
+     * side.
+     */
+    public boolean pingBinder();
+
+    /**
+     * Check to see if the process that the binder is in is still alive.
+     *
+     * @return false if the process is not alive.  Note that if it returns
+     * true, the process may have died while the call is returning.
+     */
+    public boolean isBinderAlive();
+    
+    /**
+     * Attempt to retrieve a local implementation of an interface
+     * for this Binder object.  If null is returned, you will need
+     * to instantiate a proxy class to marshall calls through
+     * the transact() method.
+     */
+    public IInterface queryLocalInterface(String descriptor);
+    
+    /**
+     * Print the object's state into the given stream.
+     * 
+     * @param fd The raw file descriptor that the dump is being sent to.
+     * @param args additional arguments to the dump request.
+     */
+    public void dump(FileDescriptor fd, String[] args) throws RemoteException;
+    
+    /**
+     * Perform a generic operation with the object.
+     * 
+     * @param code The action to perform.  This should
+     * be a number between {@link #FIRST_CALL_TRANSACTION} and
+     * {@link #LAST_CALL_TRANSACTION}.
+     * @param data Marshalled data to send to the target.  Most not be null.
+     * If you are not sending any data, you must create an empty Parcel
+     * that is given here.
+     * @param reply Marshalled data to be received from the target.  May be
+     * null if you are not interested in the return value.
+     * @param flags Additional operation flags.  Either 0 for a normal
+     * RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
+     */
+    public boolean transact(int code, Parcel data, Parcel reply, int flags)
+        throws RemoteException;
+
+    /**
+     * Interface for receiving a callback when the process hosting an IBinder
+     * has gone away.
+     * 
+     * @see #linkToDeath
+     */
+    public interface DeathRecipient {
+        public void binderDied();
+    }
+
+    /**
+     * Register the recipient for a notification if this binder
+     * goes away.  If this binder object unexpectedly goes away
+     * (typically because its hosting process has been killed),
+     * then the given {@link DeathRecipient}'s
+     * {@link DeathRecipient#binderDied DeathRecipient.binderDied()} method
+     * will be called.
+     * 
+     * <p>You will only receive death notifications for remote binders,
+     * as local binders by definition can't die without you dying as well.
+     * 
+     * @throws Throws {@link RemoteException} if the target IBinder's
+     * process has already died.
+     * 
+     * @see #unlinkToDeath
+     */
+    public void linkToDeath(DeathRecipient recipient, int flags)
+            throws RemoteException;
+
+    /**
+     * Remove a previously registered death notification.
+     * The recipient will no longer be called if this object
+     * dies.
+     * 
+     * @return Returns true if the <var>recipient</var> is successfully
+     * unlinked, assuring you that its
+     * {@link DeathRecipient#binderDied DeathRecipient.binderDied()} method
+     * will not be called.  Returns false if the target IBinder has already
+     * died, meaning the method has been (or soon will be) called.
+     * 
+     * @throws Throws {@link java.util.NoSuchElementException} if the given
+     * <var>recipient</var> has not been registered with the IBinder, and
+     * the IBinder is still alive.  Note that if the <var>recipient</var>
+     * was never registered, but the IBinder has already died, then this
+     * exception will <em>not</em> be thrown, and you will receive a false
+     * return value instead.
+     */
+    public boolean unlinkToDeath(DeathRecipient recipient, int flags);
+}
diff --git a/core/java/android/os/ICheckinService.aidl b/core/java/android/os/ICheckinService.aidl
new file mode 100644
index 0000000..e56b55d
--- /dev/null
+++ b/core/java/android/os/ICheckinService.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.os.IParentalControlCallback;
+
+/**
+ * System private API for direct access to the checkin service.
+ * Users should use the content provider instead.
+ *
+ * @see android.provider.Checkin
+ * {@hide}
+ */
+interface ICheckinService {
+    /** Synchronously attempt a checkin with the server, return true
+      * on success.
+      * @throws IllegalStateException whenever an error occurs.  The
+      * cause of the exception will be the real exception:
+      * IOException for network errors, JSONException for invalid
+      * server responses, etc.
+      */
+    boolean checkin();
+
+    /** Direct submission of crash data; returns after writing the crash. */
+    void reportCrashSync(in byte[] crashData);
+
+    /** Asynchronous "fire and forget" version of crash reporting. */
+    oneway void reportCrashAsync(in byte[] crashData);
+
+    /** Reboot into the recovery system and wipe all user data. */
+    void masterClear();
+
+    /**
+     * Determine if the device is under parental control. Return null if
+     * we are unable to check the parental control status.
+     */
+    void getParentalControlState(IParentalControlCallback p,
+                                 String requestingApp);
+}
diff --git a/core/java/android/os/IHardwareService.aidl b/core/java/android/os/IHardwareService.aidl
new file mode 100755
index 0000000..4f6029f
--- /dev/null
+++ b/core/java/android/os/IHardwareService.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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;
+
+/** {@hide} */
+interface IHardwareService
+{
+    // Vibrator support
+    void vibrate(long milliseconds);
+    void vibratePattern(in long[] pattern, int repeat, IBinder token);
+    void cancelVibrate();
+    
+    // flashlight support
+    boolean getFlashlightEnabled();
+    void setFlashlightEnabled(boolean on);
+    void enableCameraFlash(int milliseconds);
+    
+    // backlight support
+    void setScreenBacklight(int brightness);
+    void setKeyboardBacklight(boolean on);
+    void setButtonBacklight(boolean on);
+    
+    // LED support
+    void setLedState(int colorARGB, int onMS, int offMS);
+}
+
diff --git a/core/java/android/os/IInterface.java b/core/java/android/os/IInterface.java
new file mode 100644
index 0000000..2a2605a
--- /dev/null
+++ b/core/java/android/os/IInterface.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * Base class for Binder interfaces.  When defining a new interface,
+ * you must derive it from IInterface.
+ */
+public interface IInterface
+{
+    /**
+     * Retrieve the Binder object associated with this interface.
+     * You must use this instead of a plain cast, so that proxy objects
+     * can return the correct result.
+     */
+    public IBinder asBinder();
+}
diff --git a/core/java/android/os/IMessenger.aidl b/core/java/android/os/IMessenger.aidl
new file mode 100644
index 0000000..e4a8431
--- /dev/null
+++ b/core/java/android/os/IMessenger.aidl
@@ -0,0 +1,25 @@
+/* //device/java/android/android/app/IActivityPendingResult.aidl
+**
+** Copyright 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.os.Message;
+
+/** @hide */
+oneway interface IMessenger {
+    void send(in Message msg);
+}
diff --git a/core/java/android/os/IMountService.aidl b/core/java/android/os/IMountService.aidl
new file mode 100644
index 0000000..88dae85
--- /dev/null
+++ b/core/java/android/os/IMountService.aidl
@@ -0,0 +1,66 @@
+/* //device/java/android/android/os/IUsb.aidl
+**
+** Copyright 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;
+
+/** WARNING! Update IMountService.h and IMountService.cpp if you change this file.
+ * In particular, the ordering of the methods below must match the 
+ * _TRANSACTION enum in IMountService.cpp
+ * @hide
+ */
+interface IMountService
+{
+    /**
+     * Is mass storage support enabled?
+     */
+    boolean getMassStorageEnabled();
+
+    /**
+     * Enable or disable mass storage support.
+     */
+    void setMassStorageEnabled(boolean enabled);
+
+    /**
+     * Is mass storage connected?
+     */
+    boolean getMassStorageConnected();
+    
+    /**
+     * Mount external storage at given mount point.
+     */
+    void mountMedia(String mountPoint);
+
+    /**
+     * Safely unmount external storage at given mount point.
+     */
+    void unmountMedia(String mountPoint);
+
+    /**
+     * Format external storage given a mount point
+     */
+    void formatMedia(String mountPoint);
+
+    /**
+     * Returns true if media notification sounds are enabled.
+     */
+    boolean getPlayNotificationSounds();
+
+    /**
+     * Sets whether or not media notification sounds are played.
+     */
+    void setPlayNotificationSounds(boolean value);
+}
diff --git a/core/java/android/os/INetStatService.aidl b/core/java/android/os/INetStatService.aidl
new file mode 100644
index 0000000..a8f3de0
--- /dev/null
+++ b/core/java/android/os/INetStatService.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 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;
+
+/**
+ * Retrieves packet and byte counts for the phone data interface,
+ * and for all interfaces.
+ * Used for the data activity icon and the phone status in Settings.
+ *
+ * {@hide}
+ */
+interface INetStatService {
+    long getMobileTxPackets();
+    long getMobileRxPackets();
+    long getMobileTxBytes();
+    long getMobileRxBytes();
+    long getTotalTxPackets();
+    long getTotalRxPackets();
+    long getTotalTxBytes();
+    long getTotalRxBytes();
+}
diff --git a/core/java/android/os/IParentalControlCallback.aidl b/core/java/android/os/IParentalControlCallback.aidl
new file mode 100644
index 0000000..2f1a563
--- /dev/null
+++ b/core/java/android/os/IParentalControlCallback.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2008 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 com.google.android.net.ParentalControlState;
+
+/**
+ * This callback interface is used to deliver the parental control state to the calling application.
+ * {@hide}
+ */
+oneway interface IParentalControlCallback {
+	void onResult(in ParentalControlState state);
+}
diff --git a/core/java/android/os/IPermissionController.aidl b/core/java/android/os/IPermissionController.aidl
new file mode 100644
index 0000000..73a68f1
--- /dev/null
+++ b/core/java/android/os/IPermissionController.aidl
@@ -0,0 +1,23 @@
+/* //device/java/android/android/os/IPowerManager.aidl
+**
+** Copyright 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;
+
+/** @hide */
+interface IPermissionController {
+    boolean checkPermission(String permission, int pid, int uid);
+}
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
new file mode 100644
index 0000000..5486920
--- /dev/null
+++ b/core/java/android/os/IPowerManager.aidl
@@ -0,0 +1,33 @@
+/* //device/java/android/android/os/IPowerManager.aidl
+**
+** Copyright 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;
+
+/** @hide */
+interface IPowerManager
+{
+    void acquireWakeLock(int flags, IBinder lock, String tag);
+    void goToSleep(long time);
+    void releaseWakeLock(IBinder lock);
+    void userActivity(long when, boolean noChangeLights);
+    void userActivityWithForce(long when, boolean noChangeLights, boolean force);
+    void setPokeLock(int pokey, IBinder lock, String tag);
+    void setStayOnSetting(int val);
+    long getScreenOnTime();
+    void preventScreenOn(boolean prevent);
+    void setScreenBrightnessOverride(int brightness);
+}
diff --git a/core/java/android/os/IServiceManager.java b/core/java/android/os/IServiceManager.java
new file mode 100644
index 0000000..9a5ff47
--- /dev/null
+++ b/core/java/android/os/IServiceManager.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * Basic interface for finding and publishing system services.
+ * 
+ * An implementation of this interface is usually published as the
+ * global context object, which can be retrieved via
+ * BinderNative.getContextObject().  An easy way to retrieve this
+ * is with the static method BnServiceManager.getDefault().
+ * 
+ * @hide
+ */
+public interface IServiceManager extends IInterface
+{
+    /**
+     * Retrieve an existing service called @a name from the
+     * service manager.  Blocks for a few seconds waiting for it to be
+     * published if it does not already exist.
+     */
+    public IBinder getService(String name) throws RemoteException;
+    
+    /**
+     * Retrieve an existing service called @a name from the
+     * service manager.  Non-blocking.
+     */
+    public IBinder checkService(String name) throws RemoteException;
+
+    /**
+     * Place a new @a service called @a name into the service
+     * manager.
+     */
+    public void addService(String name, IBinder service) throws RemoteException;
+
+    /**
+     * Return a list of all currently running services.
+     */
+    public String[] listServices() throws RemoteException;
+
+    /**
+     * Assign a permission controller to the service manager.  After set, this
+     * interface is checked before any services are added.
+     */
+    public void setPermissionController(IPermissionController controller)
+            throws RemoteException;
+    
+    static final String descriptor = "android.os.IServiceManager";
+
+    int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
+    int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
+    int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
+    int LIST_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
+    int CHECK_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
+    int SET_PERMISSION_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5;
+}
diff --git a/core/java/android/os/LocalPowerManager.java b/core/java/android/os/LocalPowerManager.java
new file mode 100644
index 0000000..55d7972
--- /dev/null
+++ b/core/java/android/os/LocalPowerManager.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+/** @hide */
+public interface LocalPowerManager {
+    public static final int OTHER_EVENT = 0;
+    public static final int CHEEK_EVENT = 1;
+    public static final int TOUCH_EVENT = 2;
+    public static final int BUTTON_EVENT = 3;  // Button and trackball events.
+
+    public static final int POKE_LOCK_IGNORE_CHEEK_EVENTS = 0x1;
+    public static final int POKE_LOCK_SHORT_TIMEOUT = 0x2;
+    public static final int POKE_LOCK_MEDIUM_TIMEOUT = 0x4;
+
+    public static final int POKE_LOCK_TIMEOUT_MASK = 0x6;
+
+    void goToSleep(long time);
+    
+    // notify power manager when keyboard is opened/closed
+    void setKeyboardVisibility(boolean visible);
+
+    // when the keyguard is up, it manages the power state, and userActivity doesn't do anything.
+    void enableUserActivity(boolean enabled);
+
+    // the same as the method on PowerManager
+    public void userActivity(long time, boolean noChangeLights, int eventType);
+}
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
new file mode 100644
index 0000000..9581893
--- /dev/null
+++ b/core/java/android/os/Looper.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2006 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.Config;
+import android.util.Printer;
+
+/**
+  * Class used to run a message loop for a thread.  Threads by default do
+  * not have a message loop associated with them; to create one, call
+  * {@link #prepare} in the thread that is to run the loop, and then
+  * {@link #loop} to have it process messages until the loop is stopped.
+  * 
+  * <p>Most interaction with a message loop is through the
+  * {@link Handler} class.
+  * 
+  * <p>This is a typical example of the implementation of a Looper thread,
+  * using the separation of {@link #prepare} and {@link #loop} to create an
+  * initial Handler to communicate with the Looper.
+  * 
+  * <pre>
+  *  class LooperThread extends Thread {
+  *      public Handler mHandler;
+  *      
+  *      public void run() {
+  *          Looper.prepare();
+  *          
+  *          mHandler = new Handler() {
+  *              public void handleMessage(Message msg) {
+  *                  // process incoming messages here
+  *              }
+  *          };
+  *          
+  *          Looper.loop();
+  *      }
+  *  }</pre>
+  */
+public class Looper {
+    private static final boolean DEBUG = false;
+    private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
+
+    // sThreadLocal.get() will return null unless you've called prepare().
+    private static final ThreadLocal sThreadLocal = new ThreadLocal();
+
+    final MessageQueue mQueue;
+    volatile boolean mRun;
+    Thread mThread;
+    private Printer mLogging = null;
+    private static Looper mMainLooper = null;
+    
+     /** Initialize the current thread as a looper.
+      * This gives you a chance to create handlers that then reference
+      * this looper, before actually starting the loop. Be sure to call
+      * {@link #loop()} after calling this method, and end it by calling
+      * {@link #quit()}.
+      */
+    public static final void prepare() {
+        if (sThreadLocal.get() != null) {
+            throw new RuntimeException("Only one Looper may be created per thread");
+        }
+        sThreadLocal.set(new Looper());
+    }
+    
+    /** Initialize the current thread as a looper, marking it as an application's main 
+     *  looper. The main looper for your application is created by the Android environment,
+     *  so you should never need to call this function yourself.
+     * {@link #prepare()}
+     */
+     
+    public static final void prepareMainLooper() {
+        prepare();
+        setMainLooper(myLooper());
+        if (Process.supportsProcesses()) {
+            myLooper().mQueue.mQuitAllowed = false;
+        }
+    }
+
+    private synchronized static void setMainLooper(Looper looper) {
+        mMainLooper = looper;
+    }
+    
+    /** Returns the application's main looper, which lives in the main thread of the application.
+     */
+    public synchronized static final Looper getMainLooper() {
+        return mMainLooper;
+    }
+
+    /**
+     *  Run the message queue in this thread. Be sure to call
+     * {@link #quit()} to end the loop.
+     */
+    public static final void loop() {
+        Looper me = myLooper();
+        MessageQueue queue = me.mQueue;
+        while (true) {
+            Message msg = queue.next(); // might block
+            //if (!me.mRun) {
+            //    break;
+            //}
+            if (msg != null) {
+                if (msg.target == null) {
+                    // No target is a magic identifier for the quit message.
+                    return;
+                }
+                if (me.mLogging!= null) me.mLogging.println(
+                        ">>>>> Dispatching to " + msg.target + " "
+                        + msg.callback + ": " + msg.what
+                        );
+                msg.target.dispatchMessage(msg);
+                if (me.mLogging!= null) me.mLogging.println(
+                        "<<<<< Finished to    " + msg.target + " "
+                        + msg.callback);
+                msg.recycle();
+            }
+        }
+    }
+
+    /**
+     * Return the Looper object associated with the current thread.  Returns
+     * null if the calling thread is not associated with a Looper.
+     */
+    public static final Looper myLooper() {
+        return (Looper)sThreadLocal.get();
+    }
+
+    /**
+     * Control logging of messages as they are processed by this Looper.  If
+     * enabled, a log message will be written to <var>printer</var> 
+     * at the beginning and ending of each message dispatch, identifying the
+     * target Handler and message contents.
+     * 
+     * @param printer A Printer object that will receive log messages, or
+     * null to disable message logging.
+     */
+    public void setMessageLogging(Printer printer) {
+        mLogging = printer;
+    }
+    
+    /**
+     * Return the {@link MessageQueue} object associated with the current
+     * thread.  This must be called from a thread running a Looper, or a
+     * NullPointerException will be thrown.
+     */
+    public static final MessageQueue myQueue() {
+        return myLooper().mQueue;
+    }
+
+    private Looper() {
+        mQueue = new MessageQueue();
+        mRun = true;
+        mThread = Thread.currentThread();
+    }
+
+    public void quit() {
+        Message msg = Message.obtain();
+        // NOTE: By enqueueing directly into the message queue, the
+        // message is left with a null target.  This is how we know it is
+        // a quit message.
+        mQueue.enqueueMessage(msg, 0);
+    }
+
+    /**
+     * Return the Thread associated with this Looper.
+     * 
+     * @since CURRENT
+     * {@hide pending API Council approval}
+     */
+    public Thread getThread() {
+        return mThread;
+    }
+    
+    public void dump(Printer pw, String prefix) {
+        pw.println(prefix + this);
+        pw.println(prefix + "mRun=" + mRun);
+        pw.println(prefix + "mThread=" + mThread);
+        pw.println(prefix + "mQueue=" + ((mQueue != null) ? mQueue : "(null"));
+        if (mQueue != null) {
+            synchronized (mQueue) {
+                Message msg = mQueue.mMessages;
+                int n = 0;
+                while (msg != null) {
+                    pw.println(prefix + "  Message " + n + ": " + msg);
+                    n++;
+                    msg = msg.next;
+                }
+                pw.println(prefix + "(Total messages: " + n + ")");
+            }
+        }
+    }
+
+    public String toString() {
+        return "Looper{"
+            + Integer.toHexString(System.identityHashCode(this))
+            + "}";
+    }
+
+    static class HandlerException extends Exception {
+
+        HandlerException(Message message, Throwable cause) {
+            super(createMessage(cause), cause);
+        }
+
+        static String createMessage(Throwable cause) {
+            String causeMsg = cause.getMessage();
+            if (causeMsg == null) {
+                causeMsg = cause.toString();
+            }
+            return causeMsg;
+        }
+    }
+}
+
diff --git a/core/java/android/os/MailboxNotAvailableException.java b/core/java/android/os/MailboxNotAvailableException.java
new file mode 100644
index 0000000..574adbd
--- /dev/null
+++ b/core/java/android/os/MailboxNotAvailableException.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2006 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;
+
+/** @hide */
+public class MailboxNotAvailableException extends Throwable
+{
+  /**
+   * This exception represents the case when a request for a
+   * named, published mailbox fails because the requested name has not been published
+   */
+
+    public
+    MailboxNotAvailableException()
+    {
+    }
+
+    public
+    MailboxNotAvailableException(String s)
+    {
+        super(s);
+    }
+}
diff --git a/core/java/android/os/MemoryFile.java b/core/java/android/os/MemoryFile.java
new file mode 100644
index 0000000..76e4f47
--- /dev/null
+++ b/core/java/android/os/MemoryFile.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2008 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 java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+
+/**
+ * MemoryFile is a wrapper for the Linux ashmem driver.
+ * MemoryFiles are backed by shared memory, which can be optionally
+ * set to be purgeable.
+ * Purgeable files may have their contents reclaimed by the kernel 
+ * in low memory conditions (only if allowPurging is set to true).
+ * After a file is purged, attempts to read or write the file will
+ * cause an IOException to be thrown.
+ */
+public class MemoryFile
+{
+    private static String TAG = "MemoryFile";
+ 
+    // returns fd
+    private native int native_open(String name, int length);
+    // returns memory address for ashmem region
+    private native int native_mmap(int fd, int length);
+    private native void native_close(int fd);
+    private native int native_read(int fd, int address, byte[] buffer, 
+            int srcOffset, int destOffset, int count, boolean isUnpinned);
+    private native void native_write(int fd, int address, byte[] buffer, 
+            int srcOffset, int destOffset, int count, boolean isUnpinned);
+    private native void native_pin(int fd, boolean pin);
+
+    private int mFD;        // ashmem file descriptor
+    private int mAddress;   // address of ashmem memory
+    private int mLength;    // total length of our ashmem region
+    private boolean mAllowPurging = false;  // true if our ashmem region is unpinned
+
+    /**
+     * MemoryFile constructor.
+     *
+     * @param name optional name for the file (can be null).
+     * @param length of the memory file in bytes.
+     */
+    public MemoryFile(String name, int length) {
+        mLength = length;
+        mFD = native_open(name, length);
+        mAddress = native_mmap(mFD, length);
+    }
+
+    /**
+     * Closes and releases all resources for the memory file.
+     */
+    public void close() {
+        if (mFD > 0) {
+            native_close(mFD);
+            mFD = 0;
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        if (mFD > 0) {
+            Log.e(TAG, "MemoryFile.finalize() called while ashmem still open");
+            close();
+        }
+    }
+   
+    /**
+     * Returns the length of the memory file.
+     *
+     * @return file length.
+     */
+    public int length() {
+        return mLength;
+    }
+
+    /**
+     * Is memory file purging enabled?
+     *
+     * @return true if the file may be purged.
+     */
+    public boolean isPurgingAllowed() {
+        return mAllowPurging;
+    }
+
+    /**
+     * Enables or disables purging of the memory file.
+     *
+     * @param allowPurging true if the operating system can purge the contents
+     * of the file in low memory situations
+     * @return previous value of allowPurging
+     */
+    synchronized public boolean allowPurging(boolean allowPurging) throws IOException {
+        boolean oldValue = mAllowPurging;
+        if (oldValue != allowPurging) {
+            native_pin(mFD, !allowPurging);
+            mAllowPurging = allowPurging;
+        }
+        return oldValue;
+    }
+
+    /**
+     * Creates a new InputStream for reading from the memory file.
+     *
+     @return InputStream
+     */
+    public InputStream getInputStream() {
+        return new MemoryInputStream();
+    }
+
+    /**
+     * Creates a new OutputStream for writing to the memory file.
+     *
+     @return OutputStream
+     */
+     public OutputStream getOutputStream() {
+
+        return new MemoryOutputStream();
+    }
+
+    /**
+     * Reads bytes from the memory file.
+     * Will throw an IOException if the file has been purged.
+     *
+     * @param buffer byte array to read bytes into.
+     * @param srcOffset offset into the memory file to read from.
+     * @param destOffset offset into the byte array buffer to read into.
+     * @param count number of bytes to read.
+     * @return number of bytes read.
+     */
+    public int readBytes(byte[] buffer, int srcOffset, int destOffset, int count) 
+            throws IOException {
+        if (destOffset < 0 || destOffset > buffer.length || count < 0
+                || count > buffer.length - destOffset
+                || srcOffset < 0 || srcOffset > mLength
+                || count > mLength - srcOffset) {
+            throw new IndexOutOfBoundsException();
+        }
+        return native_read(mFD, mAddress, buffer, srcOffset, destOffset, count, mAllowPurging);
+    }
+
+    /**
+     * Write bytes to the memory file.
+     * Will throw an IOException if the file has been purged.
+     *
+     * @param buffer byte array to write bytes from.
+     * @param srcOffset offset into the byte array buffer to write from.
+     * @param destOffset offset  into the memory file to write to.
+     * @param count number of bytes to write.
+     */
+    public void writeBytes(byte[] buffer, int srcOffset, int destOffset, int count)
+            throws IOException {
+        if (srcOffset < 0 || srcOffset > buffer.length || count < 0
+                || count > buffer.length - srcOffset
+                || destOffset < 0 || destOffset > mLength
+                || count > mLength - destOffset) {
+            throw new IndexOutOfBoundsException();
+        }
+        native_write(mFD, mAddress, buffer, srcOffset, destOffset, count, mAllowPurging);
+    }
+
+    private class MemoryInputStream extends InputStream {
+
+        private int mMark = 0;
+        private int mOffset = 0;
+        private byte[] mSingleByte;
+
+        @Override
+        public int available() throws IOException {
+            if (mOffset >= mLength) {
+                return 0;
+            }
+            return mLength - mOffset;
+        }
+
+        @Override
+        public boolean markSupported() {
+            return true;
+        }
+
+        @Override
+        public void mark(int readlimit) {
+            mMark = mOffset;
+        }
+
+        @Override
+        public void reset() throws IOException {
+            mOffset = mMark;
+        }
+
+        @Override
+        public int read() throws IOException {
+            if (mSingleByte == null) {
+                mSingleByte = new byte[1];
+            }
+            int result = read(mSingleByte, 0, 1);
+            if (result != 1) {
+                throw new IOException("read() failed");
+            }
+            return mSingleByte[0];
+        }
+
+        @Override
+        public int read(byte buffer[], int offset, int count) throws IOException {
+            int result = readBytes(buffer, mOffset, offset, count);
+            if (result > 0) {
+                mOffset += result;
+            }
+            return result;
+        }
+
+        @Override
+        public long skip(long n) throws IOException {
+            if (mOffset + n > mLength) {
+                n = mLength - mOffset;
+            }
+            mOffset += n;
+            return n;
+        }
+    }
+
+    private class MemoryOutputStream extends OutputStream {
+
+        private int mOffset = 0;
+        private byte[] mSingleByte;
+
+        @Override
+        public void write(byte buffer[], int offset, int count) throws IOException {
+            writeBytes(buffer, offset, mOffset, count);
+        }
+
+        @Override
+        public void write(int oneByte) throws IOException {
+            if (mSingleByte == null) {
+                mSingleByte = new byte[1];
+            }
+            mSingleByte[0] = (byte)oneByte;
+            write(mSingleByte, 0, 1);
+        }
+    }
+}
diff --git a/core/java/android/os/Message.aidl b/core/java/android/os/Message.aidl
new file mode 100644
index 0000000..e8dbb5a
--- /dev/null
+++ b/core/java/android/os/Message.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/content/Intent.aidl
+**
+** Copyright 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;
+
+parcelable Message;
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
new file mode 100644
index 0000000..4130109
--- /dev/null
+++ b/core/java/android/os/Message.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2006 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.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * 
+ * Defines a message containing a description and arbitrary data object that can be
+ * sent to a {@link Handler}.  This object contains two extra int fields and an
+ * extra object field that allow you to not do allocations in many cases.  
+ *
+ * <p class="note">While the constructor of Message is public, the best way to get
+ * one of these is to call {@link #obtain Message.obtain()} or one of the
+ * {@link Handler#obtainMessage Handler.obtainMessage()} methods, which will pull
+ * them from a pool of recycled objects.</p>
+ */
+public final class Message implements Parcelable {
+    /**
+     * User-defined message code so that the recipient can identify 
+     * what this message is about. Each {@link Handler} has its own name-space
+     * for message codes, so you do not need to worry about yours conflicting
+     * with other handlers.
+     */
+    public int what;
+
+    // Use these fields instead of using the class's Bundle if you can. 
+    /** arg1 and arg2 are lower-cost alternatives to using {@link #setData(Bundle) setData()}
+    if you only need to store a few integer values. */
+    public int arg1; 
+
+    /** arg1 and arg2 are lower-cost alternatives to using {@link #setData(Bundle) setData()}
+    if you only need to store a few integer values.*/ 
+    public int arg2;
+
+    /** An arbitrary object to send to the recipient.  This must be null when
+     * sending messages across processes. */
+    public Object obj;
+
+    /** Optional Messenger where replies to this message can be sent.
+     */
+    public Messenger replyTo;
+    
+    /*package*/ long when;
+    
+    /*package*/ Bundle data;
+    
+    /*package*/ Handler target;     
+    
+    /*package*/ Runnable callback;   
+    
+    // sometimes we store linked lists of these things
+    /*package*/ Message next;
+
+    private static Object mPoolSync = new Object();
+    private static Message mPool;
+    private static int mPoolSize = 0;
+
+    private static final int MAX_POOL_SIZE = 10;
+    
+    /**
+     * Return a new Message instance from the global pool. Allows us to
+     * avoid allocating new objects in many cases.
+     */
+    public static Message obtain() {
+        synchronized (mPoolSync) {
+            if (mPool != null) {
+                Message m = mPool;
+                mPool = m.next;
+                m.next = null;
+                return m;
+            }
+        }
+        return new Message();
+    }
+
+    /**
+     * Same as {@link #obtain()}, but copies the values of an existing
+     * message (including its target) into the new one.
+     * @param orig Original message to copy.
+     * @return A Message object from the global pool.
+     */
+    public static Message obtain(Message orig) {
+        Message m = obtain();
+        m.what = orig.what;
+        m.arg1 = orig.arg1;
+        m.arg2 = orig.arg2;
+        m.obj = orig.obj;
+        m.replyTo = orig.replyTo;
+        if (orig.data != null) {
+            m.data = new Bundle(orig.data);
+        }
+        m.target = orig.target;
+        m.callback = orig.callback;
+
+        return m;
+    }
+
+    /**
+     * Same as {@link #obtain()}, but sets the value for the <em>target</em> member on the Message returned.
+     * @param h  Handler to assign to the returned Message object's <em>target</em> member.
+     * @return A Message object from the global pool.
+     */
+    public static Message obtain(Handler h) {
+        Message m = obtain();
+        m.target = h;
+
+        return m;
+    }
+
+    /**
+     * Same as {@link #obtain(Handler)}, but assigns a callback Runnable on
+     * the Message that is returned.
+     * @param h  Handler to assign to the returned Message object's <em>target</em> member.
+     * @param callback Runnable that will execute when the message is handled.
+     * @return A Message object from the global pool.
+     */
+    public static Message obtain(Handler h, Runnable callback) {
+        Message m = obtain();
+        m.target = h;
+        m.callback = callback;
+
+        return m;
+    }
+
+    /**
+     * Same as {@link #obtain()}, but sets the values for both <em>target</em> and
+     * <em>what</em> members on the Message.
+     * @param h  Value to assign to the <em>target</em> member.
+     * @param what  Value to assign to the <em>what</em> member.
+     * @return A Message object from the global pool.
+     */
+    public static Message obtain(Handler h, int what) {
+        Message m = obtain();
+        m.target = h;
+        m.what = what;
+
+        return m;
+    }
+
+    /**
+     * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, and <em>obj</em>
+     * members.
+     * @param h  The <em>target</em> value to set.
+     * @param what  The <em>what</em> value to set.
+     * @param obj  The <em>object</em> method to set.
+     * @return  A Message object from the global pool.
+     */
+    public static Message obtain(Handler h, int what, Object obj) {
+        Message m = obtain();
+        m.target = h;
+        m.what = what;
+        m.obj = obj;
+
+        return m;
+    }
+
+    /**
+     * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, 
+     * <em>arg1</em>, and <em>arg2</em> members.
+     * 
+     * @param h  The <em>target</em> value to set.
+     * @param what  The <em>what</em> value to set.
+     * @param arg1  The <em>arg1</em> value to set.
+     * @param arg2  The <em>arg2</em> value to set.
+     * @return  A Message object from the global pool.
+     */
+    public static Message obtain(Handler h, int what, int arg1, int arg2) {
+        Message m = obtain();
+        m.target = h;
+        m.what = what;
+        m.arg1 = arg1;
+        m.arg2 = arg2;
+
+        return m;
+    }
+
+    /**
+     * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, 
+     * <em>arg1</em>, <em>arg2</em>, and <em>obj</em> members.
+     * 
+     * @param h  The <em>target</em> value to set.
+     * @param what  The <em>what</em> value to set.
+     * @param arg1  The <em>arg1</em> value to set.
+     * @param arg2  The <em>arg2</em> value to set.
+     * @param obj  The <em>obj</em> value to set.
+     * @return  A Message object from the global pool.
+     */
+    public static Message obtain(Handler h, int what, 
+            int arg1, int arg2, Object obj) {
+        Message m = obtain();
+        m.target = h;
+        m.what = what;
+        m.arg1 = arg1;
+        m.arg2 = arg2;
+        m.obj = obj;
+
+        return m;
+    }
+
+    /**
+     * Return a Message instance to the global pool.  You MUST NOT touch
+     * the Message after calling this function -- it has effectively been
+     * freed.
+     */
+    public void recycle() {
+        synchronized (mPoolSync) {
+            if (mPoolSize < MAX_POOL_SIZE) {
+                clearForRecycle();
+                
+                next = mPool;
+                mPool = this;
+            }
+        }
+    }
+
+    /**
+     * Make this message like o.  Performs a shallow copy of the data field.
+     * Does not copy the linked list fields, nor the timestamp or
+     * target/callback of the original message.
+     */
+    public void copyFrom(Message o) {
+        this.what = o.what;
+        this.arg1 = o.arg1;
+        this.arg2 = o.arg2;
+        this.obj = o.obj;
+        this.replyTo = o.replyTo;
+
+        if (o.data != null) {
+            this.data = (Bundle) o.data.clone();
+        } else {
+            this.data = null;
+        }
+    }
+
+    /**
+     * Return the targeted delivery time of this message, in milliseconds.
+     */
+    public long getWhen() {
+        return when;
+    }
+    
+    public void setTarget(Handler target) {
+        this.target = target;
+    }
+
+    /**
+     * Retrieve the a {@link android.os.Handler Handler} implementation that
+     * will receive this message. The object must implement
+     * {@link android.os.Handler#handleMessage(android.os.Message)
+     * Handler.handleMessage()}. Each Handler has its own name-space for
+     * message codes, so you do not need to
+     * worry about yours conflicting with other handlers.
+     */
+    public Handler getTarget() {
+        return target;
+    }
+
+    /**
+     * Retrieve callback object that will execute when this message is handled.
+     * This object must implement Runnable. This is called by
+     * the <em>target</em> {@link Handler} that is receiving this Message to
+     * dispatch it.  If
+     * not set, the message will be dispatched to the receiving Handler's
+     * {@link Handler#handleMessage(Message Handler.handleMessage())}. */
+    public Runnable getCallback() {
+        return callback;
+    }
+    
+    /** 
+     * Obtains a Bundle of arbitrary data associated with this
+     * event, lazily creating it if necessary. Set this value by calling {@link #setData(Bundle)}.
+     */
+    public Bundle getData() {
+        if (data == null) {
+            data = new Bundle();
+        }
+        
+        return data;
+    }
+
+    /** 
+     * Like getData(), but does not lazily create the Bundle.  A null
+     * is returned if the Bundle does not already exist.
+     */
+    public Bundle peekData() {
+        return data;
+    }
+
+    /** Sets a Bundle of arbitrary data values. Use arg1 and arg1 members 
+     * as a lower cost way to send a few simple integer values, if you can. */
+    public void setData(Bundle data) {
+        this.data = data;
+    }
+
+    /**
+     * Sends this Message to the Handler specified by {@link #getTarget}.
+     * Throws a null pointer exception if this field has not been set.
+     */
+    public void sendToTarget() {
+        target.sendMessage(this);
+    }
+
+    /*package*/ void clearForRecycle() {
+        what = 0;
+        arg1 = 0;
+        arg2 = 0;
+        obj = null;
+        replyTo = null;
+        when = 0;
+        target = null;
+        callback = null;
+        data = null;
+    }
+
+    /** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}).
+    */
+    public Message() {
+    }
+
+    public String toString() {
+        StringBuilder   b = new StringBuilder();
+        
+        b.append("{ what=");
+        b.append(what);
+
+        b.append(" when=");
+        b.append(when);
+
+        if (arg1 != 0) {
+            b.append(" arg1=");
+            b.append(arg1);
+        }
+
+        if (arg2 != 0) {
+            b.append(" arg2=");
+            b.append(arg2);
+        }
+
+        if (obj != null) {
+            b.append(" obj=");
+            b.append(obj);
+        }
+
+        b.append(" }");
+        
+        return b.toString();
+    }
+
+    public static final Parcelable.Creator<Message> CREATOR
+            = new Parcelable.Creator<Message>() {
+        public Message createFromParcel(Parcel source) {
+            Message msg = Message.obtain();
+            msg.readFromParcel(source);
+            return msg;
+        }
+        
+        public Message[] newArray(int size) {
+            return new Message[size];
+        }
+    };
+        
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel dest, int flags) {
+        if (obj != null || callback != null) {
+            throw new RuntimeException(
+                "Can't marshal objects across processes.");
+        }
+        dest.writeInt(what);
+        dest.writeInt(arg1);
+        dest.writeInt(arg2);
+        dest.writeLong(when);
+        dest.writeBundle(data);
+        Messenger.writeMessengerOrNullToParcel(replyTo, dest);
+    }
+
+    private final void readFromParcel(Parcel source) {
+        what = source.readInt();
+        arg1 = source.readInt();
+        arg2 = source.readInt();
+        when = source.readLong();
+        data = source.readBundle();
+        replyTo = Messenger.readMessengerOrNullFromParcel(source);
+    }
+}
+
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
new file mode 100644
index 0000000..caf0923
--- /dev/null
+++ b/core/java/android/os/MessageQueue.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2006 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 java.util.ArrayList;
+
+import android.util.AndroidRuntimeException;
+import android.util.Config;
+import android.util.Log;
+
+import com.android.internal.os.RuntimeInit;
+
+/**
+ * Low-level class holding the list of messages to be dispatched by a
+ * {@link Looper}.  Messages are not added directly to a MessageQueue,
+ * but rather through {@link Handler} objects associated with the Looper.
+ * 
+ * <p>You can retrieve the MessageQueue for the current thread with
+ * {@link Looper#myQueue() Looper.myQueue()}.
+ */
+public class MessageQueue {
+    Message mMessages;
+    private final ArrayList mIdleHandlers = new ArrayList();
+    private boolean mQuiting = false;
+    boolean mQuitAllowed = true;
+    
+    /**
+     * Callback interface for discovering when a thread is going to block
+     * waiting for more messages.
+     */
+    public static interface IdleHandler {
+        /**
+         * Called when the message queue has run out of messages and will now
+         * wait for more.  Return true to keep your idle handler active, false
+         * to have it removed.  This may be called if there are still messages
+         * pending in the queue, but they are all scheduled to be dispatched
+         * after the current time.
+         */
+        boolean queueIdle();
+    }
+
+    /**
+     * Add a new {@link IdleHandler} to this message queue.  This may be
+     * removed automatically for you by returning false from
+     * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
+     * invoked, or explicitly removing it with {@link #removeIdleHandler}.
+     * 
+     * <p>This method is safe to call from any thread.
+     * 
+     * @param handler The IdleHandler to be added.
+     */
+    public final void addIdleHandler(IdleHandler handler) {
+        if (handler == null) {
+            throw new NullPointerException("Can't add a null IdleHandler");
+        }
+        synchronized (this) {
+            mIdleHandlers.add(handler);
+        }
+    }
+
+    /**
+     * Remove an {@link IdleHandler} from the queue that was previously added
+     * with {@link #addIdleHandler}.  If the given object is not currently
+     * in the idle list, nothing is done.
+     * 
+     * @param handler The IdleHandler to be removed.
+     */
+    public final void removeIdleHandler(IdleHandler handler) {
+        synchronized (this) {
+            mIdleHandlers.remove(handler);
+        }
+    }
+
+    MessageQueue() {
+    }
+
+    final Message next() {
+        boolean tryIdle = true;
+
+        while (true) {
+            long now;
+            Object[] idlers = null;
+    
+            // Try to retrieve the next message, returning if found.
+            synchronized (this) {
+                now = SystemClock.uptimeMillis();
+                Message msg = pullNextLocked(now);
+                if (msg != null) return msg;
+                if (tryIdle && mIdleHandlers.size() > 0) {
+                    idlers = mIdleHandlers.toArray();
+                }
+            }
+    
+            // There was no message so we are going to wait...  but first,
+            // if there are any idle handlers let them know.
+            boolean didIdle = false;
+            if (idlers != null) {
+                for (Object idler : idlers) {
+                    boolean keep = false;
+                    try {
+                        didIdle = true;
+                        keep = ((IdleHandler)idler).queueIdle();
+                    } catch (Throwable t) {
+                        Log.e("MessageQueue",
+                              "IdleHandler threw exception", t);
+                        RuntimeInit.crash("MessageQueue", t);
+                    }
+
+                    if (!keep) {
+                        synchronized (this) {
+                            mIdleHandlers.remove(idler);
+                        }
+                    }
+                }
+            }
+            
+            // While calling an idle handler, a new message could have been
+            // delivered...  so go back and look again for a pending message.
+            if (didIdle) {
+                tryIdle = false;
+                continue;
+            }
+
+            synchronized (this) {
+                // No messages, nobody to tell about it...  time to wait!
+                try {
+                    if (mMessages != null) {
+                        if (mMessages.when-now > 0) {
+                            Binder.flushPendingCommands();
+                            this.wait(mMessages.when-now);
+                        }
+                    } else {
+                        Binder.flushPendingCommands();
+                        this.wait();
+                    }
+                }
+                catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    final Message pullNextLocked(long now) {
+        Message msg = mMessages;
+        if (msg != null) {
+            if (now >= msg.when) {
+                mMessages = msg.next;
+                if (Config.LOGV) Log.v(
+                    "MessageQueue", "Returning message: " + msg);
+                return msg;
+            }
+        }
+
+        return null;
+    }
+
+    final boolean enqueueMessage(Message msg, long when) {
+        if (msg.when != 0) {
+            throw new AndroidRuntimeException(msg
+                    + " This message is already in use.");
+        }
+        if (msg.target == null && !mQuitAllowed) {
+            throw new RuntimeException("Main thread not allowed to quit");
+        }
+        synchronized (this) {
+            if (mQuiting) {
+                RuntimeException e = new RuntimeException(
+                    msg.target + " sending message to a Handler on a dead thread");
+                Log.w("MessageQueue", e.getMessage(), e);
+                return false;
+            } else if (msg.target == null) {
+                mQuiting = true;
+            }
+
+            msg.when = when;
+            //Log.d("MessageQueue", "Enqueing: " + msg);
+            Message p = mMessages;
+            if (p == null || when == 0 || when < p.when) {
+                msg.next = p;
+                mMessages = msg;
+                this.notify();
+            } else {
+                Message prev = null;
+                while (p != null && p.when <= when) {
+                    prev = p;
+                    p = p.next;
+                }
+                msg.next = prev.next;
+                prev.next = msg;
+                this.notify();
+            }
+        }
+        return true;
+    }
+
+    final boolean removeMessages(Handler h, int what, Object object,
+            boolean doRemove) {
+        synchronized (this) {
+            Message p = mMessages;
+            boolean found = false;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h && p.what == what
+                   && (object == null || p.obj == object)) {
+                if (!doRemove) return true;
+                found = true;
+                Message n = p.next;
+                mMessages = n;
+                p.recycle();
+                p = n;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && n.what == what
+                        && (object == null || n.obj == object)) {
+                        if (!doRemove) return true;
+                        found = true;
+                        Message nn = n.next;
+                        n.recycle();
+                        p.next = nn;
+                        continue;
+                    }
+                }
+                p = n;
+            }
+            
+            return found;
+        }
+    }
+
+    final void removeMessages(Handler h, Runnable r, Object object) {
+        if (r == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h && p.callback == r
+                   && (object == null || p.obj == object)) {
+                Message n = p.next;
+                mMessages = n;
+                p.recycle();
+                p = n;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && n.callback == r
+                        && (object == null || n.obj == object)) {
+                        Message nn = n.next;
+                        n.recycle();
+                        p.next = nn;
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
+    final void removeCallbacksAndMessages(Handler h, Object object) {
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h
+                    && (object == null || p.obj == object)) {
+                Message n = p.next;
+                mMessages = n;
+                p.recycle();
+                p = n;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && (object == null || n.obj == object)) {
+                        Message nn = n.next;
+                        n.recycle();
+                        p.next = nn;
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
+    /*
+    private void dumpQueue_l()
+    {
+        Message p = mMessages;
+        System.out.println(this + "  queue is:");
+        while (p != null) {
+            System.out.println("            " + p);
+            p = p.next;
+        }
+    }
+    */
+
+    void poke()
+    {
+        synchronized (this) {
+            this.notify();
+        }
+    }
+}
diff --git a/core/java/android/os/Messenger.aidl b/core/java/android/os/Messenger.aidl
new file mode 100644
index 0000000..e6b8886
--- /dev/null
+++ b/core/java/android/os/Messenger.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/content/Intent.aidl
+**
+** Copyright 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;
+
+parcelable Messenger;
diff --git a/core/java/android/os/Messenger.java b/core/java/android/os/Messenger.java
new file mode 100644
index 0000000..1bc554e
--- /dev/null
+++ b/core/java/android/os/Messenger.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * Reference to a Handler, which others can use to send messages to it.
+ * This allows for the implementation of message-based communication across
+ * processes, by creating a Messenger pointing to a Handler in one process,
+ * and handing that Messenger to another process.
+ */
+public final class Messenger implements Parcelable {
+    private final IMessenger mTarget;
+
+    /**
+     * Create a new Messenger pointing to the given Handler.  Any Message
+     * objects sent through this Messenger will appear in the Handler as if
+     * {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
+     * be called directly.
+     * 
+     * @param target The Handler that will receive sent messages.
+     */
+    public Messenger(Handler target) {
+        mTarget = target.getIMessenger();
+    }
+    
+    /**
+     * Send a Message to this Messenger's Handler.
+     * 
+     * @param message The Message to send.  Usually retrieved through
+     * {@link Message#obtain() Message.obtain()}.
+     * 
+     * @throws RemoteException Throws DeadObjectException if the target
+     * Handler no longer exists.
+     */
+    public void send(Message message) throws RemoteException {
+        mTarget.send(message);
+    }
+    
+    /**
+     * Retrieve the IBinder that this Messenger is using to communicate with
+     * its associated Handler.
+     * 
+     * @return Returns the IBinder backing this Messenger.
+     */
+    public IBinder getBinder() {
+        return mTarget.asBinder();
+    }
+    
+    /**
+     * Comparison operator on two Messenger objects, such that true
+     * is returned then they both point to the same Handler.
+     */
+    public boolean equals(Object otherObj) {
+        if (otherObj == null) {
+            return false;
+        }
+        try {
+            return mTarget.asBinder().equals(((Messenger)otherObj)
+                    .mTarget.asBinder());
+        } catch (ClassCastException e) {
+        }
+        return false;
+    }
+
+    public int hashCode() {
+        return mTarget.asBinder().hashCode();
+    }
+    
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeStrongBinder(mTarget.asBinder());
+    }
+
+    public static final Parcelable.Creator<Messenger> CREATOR
+            = new Parcelable.Creator<Messenger>() {
+        public Messenger createFromParcel(Parcel in) {
+            IBinder target = in.readStrongBinder();
+            return target != null ? new Messenger(target) : null;
+        }
+
+        public Messenger[] newArray(int size) {
+            return new Messenger[size];
+        }
+    };
+
+    /**
+     * Convenience function for writing either a Messenger or null pointer to
+     * a Parcel.  You must use this with {@link #readMessengerOrNullFromParcel}
+     * for later reading it.
+     * 
+     * @param messenger The Messenger to write, or null.
+     * @param out Where to write the Messenger.
+     */
+    public static void writeMessengerOrNullToParcel(Messenger messenger,
+            Parcel out) {
+        out.writeStrongBinder(messenger != null ? messenger.mTarget.asBinder()
+                : null);
+    }
+    
+    /**
+     * Convenience function for reading either a Messenger or null pointer from
+     * a Parcel.  You must have previously written the Messenger with
+     * {@link #writeMessengerOrNullToParcel}.
+     * 
+     * @param in The Parcel containing the written Messenger.
+     * 
+     * @return Returns the Messenger read from the Parcel, or null if null had
+     * been written.
+     */
+    public static Messenger readMessengerOrNullFromParcel(Parcel in) {
+        IBinder b = in.readStrongBinder();
+        return b != null ? new Messenger(b) : null;
+    }
+    
+    /**
+     * Create a Messenger from a raw IBinder, which had previously been
+     * retrieved with {@link #getBinder}.
+     * 
+     * @param target The IBinder this Messenger should communicate with.
+     */
+    public Messenger(IBinder target) {
+        mTarget = IMessenger.Stub.asInterface(target);
+    }
+}
diff --git a/core/java/android/os/NetStat.java b/core/java/android/os/NetStat.java
new file mode 100644
index 0000000..e294cdf
--- /dev/null
+++ b/core/java/android/os/NetStat.java
@@ -0,0 +1,247 @@
+/*
+ * 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 java.io.File;
+import java.io.RandomAccessFile;
+import java.io.IOException;
+
+/** @hide */
+public class NetStat {
+
+    // Logging tag.
+    private final static String TAG = "netstat";
+
+    // We pre-create all the File objects so we don't spend a lot of
+    // CPU at runtime converting from Java Strings to byte[] for the
+    // kernel calls.
+    private final static File[] MOBILE_TX_PACKETS = mobileFiles("tx_packets");
+    private final static File[] MOBILE_RX_PACKETS = mobileFiles("rx_packets");
+    private final static File[] MOBILE_TX_BYTES = mobileFiles("tx_bytes");
+    private final static File[] MOBILE_RX_BYTES = mobileFiles("rx_bytes");
+    private final static File SYS_CLASS_NET_DIR = new File("/sys/class/net");
+
+    /**
+     * Get total number of tx packets sent through rmnet0 or ppp0
+     *
+     * @return number of Tx packets through rmnet0 or ppp0
+     */
+    public static long getMobileTxPkts() {
+        return getMobileStat(MOBILE_TX_PACKETS);
+    }
+
+    /**
+     *  Get total number of rx packets received through rmnet0 or ppp0
+     *
+     * @return number of Rx packets through rmnet0 or ppp0
+     */
+    public static long getMobileRxPkts() {
+        return getMobileStat(MOBILE_RX_PACKETS);
+    }
+
+    /**
+     *  Get total number of tx bytes received through rmnet0 or ppp0
+     *
+     * @return number of Tx bytes through rmnet0 or ppp0
+     */
+      public static long getMobileTxBytes() {
+          return getMobileStat(MOBILE_TX_BYTES);
+      }
+
+    /**
+     *  Get total number of rx bytes received through rmnet0 or ppp0
+     *
+     * @return number of Rx bytes through rmnet0 or ppp0
+     */
+    public static long getMobileRxBytes() {
+        return getMobileStat(MOBILE_RX_BYTES);
+    }
+
+    /**
+     * Get the total number of packets sent through all network interfaces.
+     *
+     * @return the number of packets sent through all network interfaces
+     */
+    public static long getTotalTxPkts() {
+        return getTotalStat("tx_packets");
+    }
+
+    /**
+     * Get the total number of packets received through all network interfaces.
+     *
+     * @return the number of packets received through all network interfaces
+     */
+    public static long getTotalRxPkts() {
+        return getTotalStat("rx_packets");
+    }
+
+    /**
+     * Get the total number of bytes sent through all network interfaces.
+     *
+     * @return the number of bytes sent through all network interfaces
+     */
+    public static long getTotalTxBytes() {
+        return getTotalStat("tx_bytes");
+    }
+
+    /**
+     * Get the total number of bytes received through all network interfaces.
+     *
+     * @return the number of bytes received through all network interfaces
+     */
+    public static long getTotalRxBytes() {
+        return getTotalStat("rx_bytes");
+    }
+
+    /**
+     * Gets network bytes sent for this UID.
+     * The statistics are across all interfaces.
+     * The statistics come from /proc/uid_stat.
+     *
+     * {@see android.os.Process#myUid()}.
+     *
+     * @param uid
+     * @return byte count
+     */
+    public static long getUidTxBytes(int uid) {
+        return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_snd");
+    }
+
+    /**
+     * Gets network bytes received for this UID.
+     * The statistics are across all interfaces.
+     * The statistics come from /proc/uid_stat.
+     *
+     * {@see android.os.Process#myUid()}.
+     *
+     * @param uid
+     * @return byte count
+     */
+    public static long getUidRxBytes(int uid) {
+        return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_rcv");
+    }
+
+    /**
+     * Returns the array of two possible File locations for a given
+     * statistic.
+     */
+    private static File[] mobileFiles(String whatStat) {
+        // Note that we stat them at runtime to see which is
+        // available, rather than here, to guard against the files
+        // coming & going later as modules shut down (e.g. airplane
+        // mode) and whatnot.  The runtime stat() isn't expensive compared
+        // to the previous charset conversion that happened before we
+        // were reusing File instances.
+        File[] files = new File[2];
+        files[0] = new File("/sys/class/net/rmnet0/statistics/" + whatStat);
+        files[1] = new File("/sys/class/net/ppp0/statistics/" + whatStat);
+        return files;
+    }
+
+    private static long getTotalStat(String whatStat) {
+        File netdir = new File("/sys/class/net");
+
+        File[] nets = SYS_CLASS_NET_DIR.listFiles();
+        if (nets == null) {
+            return 0;
+        }
+        long total = 0;
+        StringBuffer strbuf = new StringBuffer();
+        for (File net : nets) {
+            strbuf.append(net.getPath()).append(File.separator).append("statistics")
+                    .append(File.separator).append(whatStat);
+            total += getNumberFromFilePath(strbuf.toString());
+            strbuf.setLength(0);
+        }
+        return total;
+    }
+
+    private static long getMobileStat(File[] files) {
+        for (int i = 0; i < files.length; i++) {
+            File file = files[i];
+            if (!file.exists()) {
+                continue;
+            }
+            try {
+                RandomAccessFile raf = new RandomAccessFile(file, "r");
+                return getNumberFromFile(raf, file.getAbsolutePath());
+            } catch (IOException e) {
+                Log.w(TAG,
+                      "Exception opening TCP statistics file " + file.getAbsolutePath(),
+                      e);
+            }
+        }
+        return 0L;
+    }
+
+    // File will have format <number><newline>
+    private static long getNumberFromFilePath(String filename) {
+        RandomAccessFile raf = getFile(filename);
+        if (raf == null) {
+            return 0L;
+        }
+        return getNumberFromFile(raf, filename);
+    }
+
+    // Private buffer for getNumberFromFile.  Safe for re-use because
+    // getNumberFromFile is synchronized.
+    private final static byte[] buf = new byte[16];
+
+    private static synchronized long getNumberFromFile(RandomAccessFile raf, String filename) {
+        try {
+            raf.read(buf);
+            raf.close();
+        } catch (IOException e) {
+            Log.w(TAG, "Exception getting TCP bytes from " + filename, e);
+            return 0L;
+        } finally {
+            if (raf != null) {
+                try {
+                    raf.close();
+                } catch (IOException e) {
+                    Log.w(TAG, "Exception closing " + filename, e);
+                }
+            }
+        }
+
+        long num = 0L;
+        for (int i = 0; i < buf.length; i++) {
+            if (buf[i] < '0' || buf[i] > '9') {
+                break;
+            }
+            num *= 10;
+            num += buf[i] - '0';
+        }
+        return num;
+    }
+
+    private static RandomAccessFile getFile(String filename) {
+        File f = new File(filename);
+        if (!f.canRead()) {
+            return null;
+        }
+
+        try {
+            return new RandomAccessFile(f, "r");
+        } catch (IOException e) {
+            Log.w(TAG, "Exception opening TCP statistics file " + filename, e);
+            return null;
+        }
+    }
+}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
new file mode 100644
index 0000000..9a71f6e
--- /dev/null
+++ b/core/java/android/os/Parcel.java
@@ -0,0 +1,2051 @@
+/*
+ * Copyright (C) 2006 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.text.TextUtils;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Container for a message (data and object references) that can
+ * be sent through an IBinder.  A Parcel can contain both flattened data
+ * that will be unflattened on the other side of the IPC (using the various
+ * methods here for writing specific types, or the general
+ * {@link Parcelable} interface), and references to live {@link IBinder}
+ * objects that will result in the other side receiving a proxy IBinder
+ * connected with the original IBinder in the Parcel.
+ *
+ * <p class="note">Parcel is <strong>not</strong> a general-purpose
+ * serialization mechanism.  This class (and the corresponding
+ * {@link Parcelable} API for placing arbitrary objects into a Parcel) is
+ * designed as a high-performance IPC transport.  As such, it is not
+ * appropriate to place any Parcel data in to persistent storage: changes
+ * in the underlying implementation of any of the data in the Parcel can
+ * render older data unreadable.</p>
+ * 
+ * <p>The bulk of the Parcel API revolves around reading and writing data
+ * of various types.  There are six major classes of such functions available.</p>
+ * 
+ * <h3>Primitives</h3>
+ * 
+ * <p>The most basic data functions are for writing and reading primitive
+ * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble},
+ * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt},
+ * {@link #readInt}, {@link #writeLong}, {@link #readLong},
+ * {@link #writeString}, {@link #readString}.  Most other
+ * data operations are built on top of these.  The given data is written and
+ * read using the endianess of the host CPU.</p>
+ * 
+ * <h3>Primitive Arrays</h3>
+ * 
+ * <p>There are a variety of methods for reading and writing raw arrays
+ * of primitive objects, which generally result in writing a 4-byte length
+ * followed by the primitive data items.  The methods for reading can either
+ * read the data into an existing array, or create and return a new array.
+ * These available types are:</p>
+ * 
+ * <ul>
+ * <li> {@link #writeBooleanArray(boolean[])},
+ * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()}
+ * <li> {@link #writeByteArray(byte[])},
+ * {@link #writeByteArray(byte[], int, int)}, {@link #readByteArray(byte[])},
+ * {@link #createByteArray()}
+ * <li> {@link #writeCharArray(char[])}, {@link #readCharArray(char[])},
+ * {@link #createCharArray()}
+ * <li> {@link #writeDoubleArray(double[])}, {@link #readDoubleArray(double[])},
+ * {@link #createDoubleArray()}
+ * <li> {@link #writeFloatArray(float[])}, {@link #readFloatArray(float[])},
+ * {@link #createFloatArray()}
+ * <li> {@link #writeIntArray(int[])}, {@link #readIntArray(int[])},
+ * {@link #createIntArray()}
+ * <li> {@link #writeLongArray(long[])}, {@link #readLongArray(long[])},
+ * {@link #createLongArray()}
+ * <li> {@link #writeStringArray(String[])}, {@link #readStringArray(String[])},
+ * {@link #createStringArray()}.
+ * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)},
+ * {@link #readSparseBooleanArray()}.
+ * </ul>
+ * 
+ * <h3>Parcelables</h3>
+ * 
+ * <p>The {@link Parcelable} protocol provides an extremely efficient (but
+ * low-level) protocol for objects to write and read themselves from Parcels.
+ * You can use the direct methods {@link #writeParcelable(Parcelable, int)}
+ * and {@link #readParcelable(ClassLoader)} or
+ * {@link #writeParcelableArray} and
+ * {@link #readParcelableArray(ClassLoader)} to write or read.  These
+ * methods write both the class type and its data to the Parcel, allowing
+ * that class to be reconstructed from the appropriate class loader when
+ * later reading.</p>
+ * 
+ * <p>There are also some methods that provide a more efficient way to work
+ * with Parcelables: {@link #writeTypedArray},
+ * {@link #writeTypedList(List)},
+ * {@link #readTypedArray} and {@link #readTypedList}.  These methods
+ * do not write the class information of the original object: instead, the
+ * caller of the read function must know what type to expect and pass in the
+ * appropriate {@link Parcelable.Creator Parcelable.Creator} instead to
+ * properly construct the new object and read its data.  (To more efficient
+ * write and read a single Parceable object, you can directly call
+ * {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
+ * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
+ * yourself.)</p>
+ * 
+ * <h3>Bundles</h3>
+ * 
+ * <p>A special type-safe container, called {@link Bundle}, is available
+ * for key/value maps of heterogeneous values.  This has many optimizations
+ * for improved performance when reading and writing data, and its type-safe
+ * API avoids difficult to debug type errors when finally marshalling the
+ * data contents into a Parcel.  The methods to use are
+ * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and
+ * {@link #readBundle(ClassLoader)}.
+ * 
+ * <h3>Active Objects</h3>
+ * 
+ * <p>An unusual feature of Parcel is the ability to read and write active
+ * objects.  For these objects the actual contents of the object is not
+ * written, rather a special token referencing the object is written.  When
+ * reading the object back from the Parcel, you do not get a new instance of
+ * the object, but rather a handle that operates on the exact same object that
+ * was originally written.  There are two forms of active objects available.</p>
+ * 
+ * <p>{@link Binder} objects are a core facility of Android's general cross-process
+ * communication system.  The {@link IBinder} interface describes an abstract
+ * protocol with a Binder object.  Any such interface can be written in to
+ * a Parcel, and upon reading you will receive either the original object
+ * implementing that interface or a special proxy implementation
+ * that communicates calls back to the original object.  The methods to use are
+ * {@link #writeStrongBinder(IBinder)},
+ * {@link #writeStrongInterface(IInterface)}, {@link #readStrongBinder()},
+ * {@link #writeBinderArray(IBinder[])}, {@link #readBinderArray(IBinder[])},
+ * {@link #createBinderArray()},
+ * {@link #writeBinderList(List)}, {@link #readBinderList(List)},
+ * {@link #createBinderArrayList()}.</p>
+ * 
+ * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers,
+ * can be written and {@link ParcelFileDescriptor} objects returned to operate
+ * on the original file descriptor.  The returned file descriptor is a dup
+ * of the original file descriptor: the object and fd is different, but
+ * operating on the same underlying file stream, with the same position, etc.
+ * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
+ * {@link #readFileDescriptor()}.
+ * 
+ * <h3>Untyped Containers</h3>
+ * 
+ * <p>A final class of methods are for writing and reading standard Java
+ * containers of arbitrary types.  These all revolve around the
+ * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods
+ * which define the types of objects allowed.  The container methods are
+ * {@link #writeArray(Object[])}, {@link #readArray(ClassLoader)},
+ * {@link #writeList(List)}, {@link #readList(List, ClassLoader)},
+ * {@link #readArrayList(ClassLoader)},
+ * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)},
+ * {@link #writeSparseArray(SparseArray)},
+ * {@link #readSparseArray(ClassLoader)}.
+ */
+public final class Parcel {
+    private static final boolean DEBUG_RECYCLE = false;
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    private int mObject; // used by native code
+    @SuppressWarnings({"UnusedDeclaration"})
+    private int mOwnObject; // used by native code
+    private RuntimeException mStack;
+
+    private static final int POOL_SIZE = 6;
+    private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE];
+    private static final Parcel[] sHolderPool = new Parcel[POOL_SIZE];
+
+    private static final int VAL_NULL = -1;
+    private static final int VAL_STRING = 0;
+    private static final int VAL_INTEGER = 1;
+    private static final int VAL_MAP = 2;
+    private static final int VAL_BUNDLE = 3;
+    private static final int VAL_PARCELABLE = 4;
+    private static final int VAL_SHORT = 5;
+    private static final int VAL_LONG = 6;
+    private static final int VAL_FLOAT = 7;
+    private static final int VAL_DOUBLE = 8;
+    private static final int VAL_BOOLEAN = 9;
+    private static final int VAL_CHARSEQUENCE = 10;
+    private static final int VAL_LIST  = 11;
+    private static final int VAL_SPARSEARRAY = 12;
+    private static final int VAL_BYTEARRAY = 13;
+    private static final int VAL_STRINGARRAY = 14;
+    private static final int VAL_IBINDER = 15;
+    private static final int VAL_PARCELABLEARRAY = 16;
+    private static final int VAL_OBJECTARRAY = 17;
+    private static final int VAL_INTARRAY = 18;
+    private static final int VAL_LONGARRAY = 19;
+    private static final int VAL_BYTE = 20;
+    private static final int VAL_SERIALIZABLE = 21;
+    private static final int VAL_SPARSEBOOLEANARRAY = 22;
+    private static final int VAL_BOOLEANARRAY = 23;
+
+    private static final int EX_SECURITY = -1;
+    private static final int EX_BAD_PARCELABLE = -2;
+    private static final int EX_ILLEGAL_ARGUMENT = -3;
+    private static final int EX_NULL_POINTER = -4;
+    private static final int EX_ILLEGAL_STATE = -5;
+    
+    public final static Parcelable.Creator<String> STRING_CREATOR
+             = new Parcelable.Creator<String>() {
+        public String createFromParcel(Parcel source) {
+            return source.readString();
+        }
+        public String[] newArray(int size) {
+            return new String[size];
+        }
+    };
+
+    /**
+     * Retrieve a new Parcel object from the pool.
+     */
+    public static Parcel obtain() {
+        final Parcel[] pool = sOwnedPool;
+        synchronized (pool) {
+            Parcel p;
+            for (int i=0; i<POOL_SIZE; i++) {
+                p = pool[i];
+                if (p != null) {
+                    pool[i] = null;
+                    if (DEBUG_RECYCLE) {
+                        p.mStack = new RuntimeException();
+                    }
+                    return p;
+                }
+            }
+        }
+        return new Parcel(0);
+    }
+
+    /**
+     * Put a Parcel object back into the pool.  You must not touch
+     * the object after this call.
+     */
+    public final void recycle() {
+        if (DEBUG_RECYCLE) mStack = null;
+        freeBuffer();
+        final Parcel[] pool = mOwnObject != 0 ? sOwnedPool : sHolderPool;
+        synchronized (pool) {
+            for (int i=0; i<POOL_SIZE; i++) {
+                if (pool[i] == null) {
+                    pool[i] = this;
+                    return;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the total amount of data contained in the parcel.
+     */
+    public final native int dataSize();
+
+    /**
+     * Returns the amount of data remaining to be read from the
+     * parcel.  That is, {@link #dataSize}-{@link #dataPosition}.
+     */
+    public final native int dataAvail();
+
+    /**
+     * Returns the current position in the parcel data.  Never
+     * more than {@link #dataSize}.
+     */
+    public final native int dataPosition();
+
+    /**
+     * Returns the total amount of space in the parcel.  This is always
+     * >= {@link #dataSize}.  The difference between it and dataSize() is the
+     * amount of room left until the parcel needs to re-allocate its
+     * data buffer.
+     */
+    public final native int dataCapacity();
+
+    /**
+     * Change the amount of data in the parcel.  Can be either smaller or
+     * larger than the current size.  If larger than the current capacity,
+     * more memory will be allocated.
+     *
+     * @param size The new number of bytes in the Parcel.
+     */
+    public final native void setDataSize(int size);
+
+    /**
+     * Move the current read/write position in the parcel.
+     * @param pos New offset in the parcel; must be between 0 and
+     * {@link #dataSize}.
+     */
+    public final native void setDataPosition(int pos);
+
+    /**
+     * Change the capacity (current available space) of the parcel.
+     *
+     * @param size The new capacity of the parcel, in bytes.  Can not be
+     * less than {@link #dataSize} -- that is, you can not drop existing data
+     * with this method.
+     */
+    public final native void setDataCapacity(int size);
+
+    /**
+     * Returns the raw bytes of the parcel.
+     *
+     * <p class="note">The data you retrieve here <strong>must not</strong>
+     * be placed in any kind of persistent storage (on local disk, across
+     * a network, etc).  For that, you should use standard serialization
+     * or another kind of general serialization mechanism.  The Parcel
+     * marshalled representation is highly optimized for local IPC, and as
+     * such does not attempt to maintain compatibility with data created
+     * in different versions of the platform.
+     */
+    public final native byte[] marshall();
+
+    /**
+     * Set the bytes in data to be the raw bytes of this Parcel.
+     */
+    public final native void unmarshall(byte[] data, int offest, int length);
+
+    public final native void appendFrom(Parcel parcel, int offset, int length);
+
+    /**
+     * Report whether the parcel contains any marshalled file descriptors.
+     */
+    public final native boolean hasFileDescriptors();
+
+    /**
+     * Store or read an IBinder interface token in the parcel at the current
+     * {@link #dataPosition}.  This is used to validate that the marshalled
+     * transaction is intended for the target interface.
+     */
+    public final native void writeInterfaceToken(String interfaceName);
+    public final native void enforceInterface(String interfaceName);
+
+    /**
+     * Write a byte array into the parcel at the current {#link #dataPosition},
+     * growing {@link #dataCapacity} if needed.
+     * @param b Bytes to place into the parcel.
+     */
+    public final void writeByteArray(byte[] b) {
+        writeByteArray(b, 0, (b != null) ? b.length : 0);
+    }
+
+    /**
+     * Write an byte array into the parcel at the current {#link #dataPosition},
+     * growing {@link #dataCapacity} if needed.
+     * @param b Bytes to place into the parcel.
+     * @param offset Index of first byte to be written.
+     * @param len Number of bytes to write.
+     */
+    public final void writeByteArray(byte[] b, int offset, int len) {
+        if (b == null) {
+            writeInt(-1);
+            return;
+        }
+        if (b.length < offset + len || len < 0 || offset < 0) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        writeNative(b, offset, len);
+    }
+
+    private native void writeNative(byte[] b, int offset, int len);
+
+    /**
+     * Write an integer value into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     */
+    public final native void writeInt(int val);
+
+    /**
+     * Write a long integer value into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     */
+    public final native void writeLong(long val);
+
+    /**
+     * Write a floating point value into the parcel at the current
+     * dataPosition(), growing dataCapacity() if needed.
+     */
+    public final native void writeFloat(float val);
+
+    /**
+     * Write a double precision floating point value into the parcel at the
+     * current dataPosition(), growing dataCapacity() if needed.
+     */
+    public final native void writeDouble(double val);
+
+    /**
+     * Write a string value into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     */
+    public final native void writeString(String val);
+
+    /**
+     * Write an object into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     */
+    public final native void writeStrongBinder(IBinder val);
+
+    /**
+     * Write an object into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     */
+    public final void writeStrongInterface(IInterface val) {
+        writeStrongBinder(val == null ? null : val.asBinder());
+    }
+
+    /**
+     * Write a FileDescriptor into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     */
+    public final native void writeFileDescriptor(FileDescriptor val);
+
+    /**
+     * Write an byte value into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     */
+    public final void writeByte(byte val) {
+        writeInt(val);
+    }
+
+    /**
+     * Please use {@link #writeBundle} instead.  Flattens a Map into the parcel
+     * at the current dataPosition(),
+     * growing dataCapacity() if needed.  The Map keys must be String objects.
+     * The Map values are written using {@link #writeValue} and must follow
+     * the specification there.
+     * 
+     * <p>It is strongly recommended to use {@link #writeBundle} instead of
+     * this method, since the Bundle class provides a type-safe API that
+     * allows you to avoid mysterious type errors at the point of marshalling.
+     */
+    public final void writeMap(Map val) {
+        writeMapInternal((Map<String,Object>) val);
+    }
+
+    /**
+     * Flatten a Map into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.  The Map keys must be String objects.
+     */
+    private void writeMapInternal(Map<String,Object> val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+        Set<Map.Entry<String,Object>> entries = val.entrySet();
+        writeInt(entries.size());
+        for (Map.Entry<String,Object> e : entries) {
+            writeValue(e.getKey());
+            writeValue(e.getValue());
+        }
+    }
+
+    /**
+     * Flatten a Bundle into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.
+     */
+    public final void writeBundle(Bundle val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+
+        if (val.mParcelledData != null) {
+            int length = val.mParcelledData.dataSize();
+            appendFrom(val.mParcelledData, 0, length);
+        } else {
+            writeInt(-1); // dummy, will hold length
+            int oldPos = dataPosition();
+            writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+
+            writeMapInternal(val.mMap);
+            int newPos = dataPosition();
+
+            // Backpatch length
+            setDataPosition(oldPos - 4);
+            int length = newPos - oldPos;
+            writeInt(length);
+            setDataPosition(newPos);
+        }
+    }
+
+    /**
+     * Flatten a List into the parcel at the current dataPosition(), growing
+     * dataCapacity() if needed.  The List values are written using
+     * {@link #writeValue} and must follow the specification there.
+     */
+    public final void writeList(List val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+        int N = val.size();
+        int i=0;
+        writeInt(N);
+        while (i < N) {
+            writeValue(val.get(i));
+            i++;
+        }
+    }
+
+    /**
+     * Flatten an Object array into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.  The array values are written using
+     * {@link #writeValue} and must follow the specification there.
+     */
+    public final void writeArray(Object[] val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+        int N = val.length;
+        int i=0;
+        writeInt(N);
+        while (i < N) {
+            writeValue(val[i]);
+            i++;
+        }
+    }
+
+    /**
+     * Flatten a generic SparseArray into the parcel at the current
+     * dataPosition(), growing dataCapacity() if needed.  The SparseArray
+     * values are written using {@link #writeValue} and must follow the
+     * specification there.
+     */
+    public final void writeSparseArray(SparseArray<Object> val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+        int N = val.size();
+        writeInt(N);
+        int i=0;
+        while (i < N) {
+            writeInt(val.keyAt(i));
+            writeValue(val.valueAt(i));
+            i++;
+        }
+    }
+
+    public final void writeSparseBooleanArray(SparseBooleanArray val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+        int N = val.size();
+        writeInt(N);
+        int i=0;
+        while (i < N) {
+            writeInt(val.keyAt(i));
+            writeByte((byte)(val.valueAt(i) ? 1 : 0));
+            i++;
+        }
+    }
+
+    public final void writeBooleanArray(boolean[] val) {
+        if (val != null) {
+            int N = val.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeInt(val[i] ? 1 : 0);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    public final boolean[] createBooleanArray() {
+        int N = readInt();
+        // >>2 as a fast divide-by-4 works in the create*Array() functions
+        // because dataAvail() will never return a negative number.  4 is
+        // the size of a stored boolean in the stream.
+        if (N >= 0 && N <= (dataAvail() >> 2)) {
+            boolean[] val = new boolean[N];
+            for (int i=0; i<N; i++) {
+                val[i] = readInt() != 0;
+            }
+            return val;
+        } else {
+            return null;
+        }
+    }
+
+    public final void readBooleanArray(boolean[] val) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                val[i] = readInt() != 0;
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    public final void writeCharArray(char[] val) {
+        if (val != null) {
+            int N = val.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeInt((int)val[i]);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    public final char[] createCharArray() {
+        int N = readInt();
+        if (N >= 0 && N <= (dataAvail() >> 2)) {
+            char[] val = new char[N];
+            for (int i=0; i<N; i++) {
+                val[i] = (char)readInt();
+            }
+            return val;
+        } else {
+            return null;
+        }
+    }
+
+    public final void readCharArray(char[] val) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                val[i] = (char)readInt();
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    public final void writeIntArray(int[] val) {
+        if (val != null) {
+            int N = val.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeInt(val[i]);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    public final int[] createIntArray() {
+        int N = readInt();
+        if (N >= 0 && N <= (dataAvail() >> 2)) {
+            int[] val = new int[N];
+            for (int i=0; i<N; i++) {
+                val[i] = readInt();
+            }
+            return val;
+        } else {
+            return null;
+        }
+    }
+
+    public final void readIntArray(int[] val) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                val[i] = readInt();
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    public final void writeLongArray(long[] val) {
+        if (val != null) {
+            int N = val.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeLong(val[i]);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    public final long[] createLongArray() {
+        int N = readInt();
+        // >>3 because stored longs are 64 bits
+        if (N >= 0 && N <= (dataAvail() >> 3)) {
+            long[] val = new long[N];
+            for (int i=0; i<N; i++) {
+                val[i] = readLong();
+            }
+            return val;
+        } else {
+            return null;
+        }
+    }
+
+    public final void readLongArray(long[] val) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                val[i] = readLong();
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    public final void writeFloatArray(float[] val) {
+        if (val != null) {
+            int N = val.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeFloat(val[i]);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    public final float[] createFloatArray() {
+        int N = readInt();
+        // >>2 because stored floats are 4 bytes
+        if (N >= 0 && N <= (dataAvail() >> 2)) {
+            float[] val = new float[N];
+            for (int i=0; i<N; i++) {
+                val[i] = readFloat();
+            }
+            return val;
+        } else {
+            return null;
+        }
+    }
+
+    public final void readFloatArray(float[] val) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                val[i] = readFloat();
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    public final void writeDoubleArray(double[] val) {
+        if (val != null) {
+            int N = val.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeDouble(val[i]);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    public final double[] createDoubleArray() {
+        int N = readInt();
+        // >>3 because stored doubles are 8 bytes
+        if (N >= 0 && N <= (dataAvail() >> 3)) {
+            double[] val = new double[N];
+            for (int i=0; i<N; i++) {
+                val[i] = readDouble();
+            }
+            return val;
+        } else {
+            return null;
+        }
+    }
+
+    public final void readDoubleArray(double[] val) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                val[i] = readDouble();
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    public final void writeStringArray(String[] val) {
+        if (val != null) {
+            int N = val.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeString(val[i]);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    public final String[] createStringArray() {
+        int N = readInt();
+        if (N >= 0) {
+            String[] val = new String[N];
+            for (int i=0; i<N; i++) {
+                val[i] = readString();
+            }
+            return val;
+        } else {
+            return null;
+        }
+    }
+
+    public final void readStringArray(String[] val) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                val[i] = readString();
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    public final void writeBinderArray(IBinder[] val) {
+        if (val != null) {
+            int N = val.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeStrongBinder(val[i]);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    public final IBinder[] createBinderArray() {
+        int N = readInt();
+        if (N >= 0) {
+            IBinder[] val = new IBinder[N];
+            for (int i=0; i<N; i++) {
+                val[i] = readStrongBinder();
+            }
+            return val;
+        } else {
+            return null;
+        }
+    }
+
+    public final void readBinderArray(IBinder[] val) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                val[i] = readStrongBinder();
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    /**
+     * Flatten a List containing a particular object type into the parcel, at
+     * the current dataPosition() and growing dataCapacity() if needed.  The
+     * type of the objects in the list must be one that implements Parcelable.
+     * Unlike the generic writeList() method, however, only the raw data of the
+     * objects is written and not their type, so you must use the corresponding
+     * readTypedList() to unmarshall them.
+     *
+     * @param val The list of objects to be written.
+     *
+     * @see #createTypedArrayList
+     * @see #readTypedList
+     * @see Parcelable
+     */
+    public final <T extends Parcelable> void writeTypedList(List<T> val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+        int N = val.size();
+        int i=0;
+        writeInt(N);
+        while (i < N) {
+            T item = val.get(i);
+            if (item != null) {
+                writeInt(1);
+                item.writeToParcel(this, 0);
+            } else {
+                writeInt(0);
+            }
+            i++;
+        }
+    }
+
+    /**
+     * Flatten a List containing String objects into the parcel, at
+     * the current dataPosition() and growing dataCapacity() if needed.  They
+     * can later be retrieved with {@link #createStringArrayList} or
+     * {@link #readStringList}.
+     *
+     * @param val The list of strings to be written.
+     *
+     * @see #createStringArrayList
+     * @see #readStringList
+     */
+    public final void writeStringList(List<String> val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+        int N = val.size();
+        int i=0;
+        writeInt(N);
+        while (i < N) {
+            writeString(val.get(i));
+            i++;
+        }
+    }
+
+    /**
+     * Flatten a List containing IBinder objects into the parcel, at
+     * the current dataPosition() and growing dataCapacity() if needed.  They
+     * can later be retrieved with {@link #createBinderArrayList} or
+     * {@link #readBinderList}.
+     *
+     * @param val The list of strings to be written.
+     *
+     * @see #createBinderArrayList
+     * @see #readBinderList
+     */
+    public final void writeBinderList(List<IBinder> val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+        int N = val.size();
+        int i=0;
+        writeInt(N);
+        while (i < N) {
+            writeStrongBinder(val.get(i));
+            i++;
+        }
+    }
+
+    /**
+     * Flatten a heterogeneous array containing a particular object type into
+     * the parcel, at
+     * the current dataPosition() and growing dataCapacity() if needed.  The
+     * type of the objects in the array must be one that implements Parcelable.
+     * Unlike the {@link #writeParcelableArray} method, however, only the
+     * raw data of the objects is written and not their type, so you must use
+     * {@link #readTypedArray} with the correct corresponding
+     * {@link Parcelable.Creator} implementation to unmarshall them.
+     *
+     * @param val The array of objects to be written.
+     * @param parcelableFlags Contextual flags as per
+     * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
+     *
+     * @see #readTypedArray
+     * @see #writeParcelableArray
+     * @see Parcelable.Creator
+     */
+    public final <T extends Parcelable> void writeTypedArray(T[] val,
+            int parcelableFlags) {
+        if (val != null) {
+            int N = val.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                T item = val[i];
+                if (item != null) {
+                    writeInt(1);
+                    item.writeToParcel(this, parcelableFlags);
+                } else {
+                    writeInt(0);
+                }
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    /**
+     * Flatten a generic object in to a parcel.  The given Object value may
+     * currently be one of the following types:
+     * 
+     * <ul>
+     * <li> null
+     * <li> String
+     * <li> Byte
+     * <li> Short
+     * <li> Integer
+     * <li> Long
+     * <li> Float
+     * <li> Double
+     * <li> Boolean
+     * <li> String[]
+     * <li> boolean[]
+     * <li> byte[]
+     * <li> int[]
+     * <li> long[]
+     * <li> Object[] (supporting objects of the same type defined here).
+     * <li> {@link Bundle}
+     * <li> Map (as supported by {@link #writeMap}).
+     * <li> Any object that implements the {@link Parcelable} protocol.
+     * <li> Parcelable[]
+     * <li> CharSequence (as supported by {@link TextUtils#writeToParcel}).
+     * <li> List (as supported by {@link #writeList}).
+     * <li> {@link SparseArray} (as supported by {@link #writeSparseArray}).
+     * <li> {@link IBinder}
+     * <li> Any object that implements Serializable (but see
+     *      {@link #writeSerializable} for caveats).  Note that all of the
+     *      previous types have relatively efficient implementations for
+     *      writing to a Parcel; having to rely on the generic serialization
+     *      approach is much less efficient and should be avoided whenever
+     *      possible.
+     * </ul>
+     */
+    public final void writeValue(Object v) {
+        if (v == null) {
+            writeInt(VAL_NULL);
+        } else if (v instanceof String) {
+            writeInt(VAL_STRING);
+            writeString((String) v);
+        } else if (v instanceof Integer) {
+            writeInt(VAL_INTEGER);
+            writeInt((Integer) v);
+        } else if (v instanceof Map) {
+            writeInt(VAL_MAP);
+            writeMap((Map) v);
+        } else if (v instanceof Bundle) {
+            // Must be before Parcelable
+            writeInt(VAL_BUNDLE);
+            writeBundle((Bundle) v);
+        } else if (v instanceof Parcelable) {
+            writeInt(VAL_PARCELABLE);
+            writeParcelable((Parcelable) v, 0);
+        } else if (v instanceof Short) {
+            writeInt(VAL_SHORT);
+            writeInt(((Short) v).intValue());
+        } else if (v instanceof Long) {
+            writeInt(VAL_LONG);
+            writeLong((Long) v);
+        } else if (v instanceof Float) {
+            writeInt(VAL_FLOAT);
+            writeFloat((Float) v);
+        } else if (v instanceof Double) {
+            writeInt(VAL_DOUBLE);
+            writeDouble((Double) v);
+        } else if (v instanceof Boolean) {
+            writeInt(VAL_BOOLEAN);
+            writeInt((Boolean) v ? 1 : 0);
+        } else if (v instanceof CharSequence) {
+            // Must be after String
+            writeInt(VAL_CHARSEQUENCE);
+            TextUtils.writeToParcel((CharSequence) v, this, 0);
+        } else if (v instanceof List) {
+            writeInt(VAL_LIST);
+            writeList((List) v);
+        } else if (v instanceof SparseArray) {
+            writeInt(VAL_SPARSEARRAY);
+            writeSparseArray((SparseArray) v);
+        } else if (v instanceof boolean[]) {
+            writeInt(VAL_BOOLEANARRAY);
+            writeBooleanArray((boolean[]) v);
+        } else if (v instanceof byte[]) {
+            writeInt(VAL_BYTEARRAY);
+            writeByteArray((byte[]) v);
+        } else if (v instanceof String[]) {
+            writeInt(VAL_STRINGARRAY);
+            writeStringArray((String[]) v);
+        } else if (v instanceof IBinder) {
+            writeInt(VAL_IBINDER);
+            writeStrongBinder((IBinder) v);
+        } else if (v instanceof Parcelable[]) {
+            writeInt(VAL_PARCELABLEARRAY);
+            writeParcelableArray((Parcelable[]) v, 0);
+        } else if (v instanceof Object[]) {
+            writeInt(VAL_OBJECTARRAY);
+            writeArray((Object[]) v);
+        } else if (v instanceof int[]) {
+            writeInt(VAL_INTARRAY);
+            writeIntArray((int[]) v);
+        } else if (v instanceof long[]) {
+            writeInt(VAL_LONGARRAY);
+            writeLongArray((long[]) v);
+        } else if (v instanceof Byte) {
+            writeInt(VAL_BYTE);
+            writeInt((Byte) v);
+        } else if (v instanceof Serializable) {
+            // Must be last
+            writeInt(VAL_SERIALIZABLE);
+            writeSerializable((Serializable) v);
+        } else {
+            throw new RuntimeException("Parcel: unable to marshal value " + v);
+        }
+    }
+
+    /**
+     * Flatten the name of the class of the Parcelable and its contents
+     * into the parcel.
+     * 
+     * @param p The Parcelable object to be written.
+     * @param parcelableFlags Contextual flags as per
+     * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
+     */
+    public final void writeParcelable(Parcelable p, int parcelableFlags) {
+        if (p == null) {
+            writeString(null);
+            return;
+        }
+        String name = p.getClass().getName();
+        writeString(name);
+        p.writeToParcel(this, parcelableFlags);
+    }
+
+    /**
+     * Write a generic serializable object in to a Parcel.  It is strongly
+     * recommended that this method be avoided, since the serialization
+     * overhead is extremely large, and this approach will be much slower than
+     * using the other approaches to writing data in to a Parcel.
+     */
+    public final void writeSerializable(Serializable s) {
+        if (s == null) {
+            writeString(null);
+            return;
+        }
+        String name = s.getClass().getName();
+        writeString(name);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(s);
+            oos.close();
+
+            writeByteArray(baos.toByteArray());
+        } catch (IOException ioe) {
+            throw new RuntimeException("Parcelable encountered " +
+                "IOException writing serializable object (name = " + name +
+                ")", ioe);
+        }
+    }
+
+    /**
+     * Special function for writing an exception result at the header of
+     * a parcel, to be used when returning an exception from a transaction.
+     * Note that this currently only supports a few exception types; any other
+     * exception will be re-thrown by this function as a RuntimeException
+     * (to be caught by the system's last-resort exception handling when
+     * dispatching a transaction).
+     * 
+     * <p>The supported exception types are:
+     * <ul>
+     * <li>{@link BadParcelableException}
+     * <li>{@link IllegalArgumentException}
+     * <li>{@link IllegalStateException}
+     * <li>{@link NullPointerException}
+     * <li>{@link SecurityException}
+     * </ul>
+     * 
+     * @param e The Exception to be written.
+     *
+     * @see #writeNoException
+     * @see #readException
+     */
+    public final void writeException(Exception e) {
+        int code = 0;
+        if (e instanceof SecurityException) {
+            code = EX_SECURITY;
+        } else if (e instanceof BadParcelableException) {
+            code = EX_BAD_PARCELABLE;
+        } else if (e instanceof IllegalArgumentException) {
+            code = EX_ILLEGAL_ARGUMENT;
+        } else if (e instanceof NullPointerException) {
+            code = EX_NULL_POINTER;
+        } else if (e instanceof IllegalStateException) {
+            code = EX_ILLEGAL_STATE;
+        }
+        writeInt(code);
+        if (code == 0) {
+            if (e instanceof RuntimeException) {
+                throw (RuntimeException) e;
+            }
+            throw new RuntimeException(e);
+        }
+        writeString(e.getMessage());
+    }
+
+    /**
+     * Special function for writing information at the front of the Parcel
+     * indicating that no exception occurred.
+     *
+     * @see #writeException
+     * @see #readException
+     */
+    public final void writeNoException() {
+        writeInt(0);
+    }
+
+    /**
+     * Special function for reading an exception result from the header of
+     * a parcel, to be used after receiving the result of a transaction.  This
+     * will throw the exception for you if it had been written to the Parcel,
+     * otherwise return and let you read the normal result data from the Parcel.
+     *
+     * @see #writeException
+     * @see #writeNoException
+     */
+    public final void readException() {
+        int code = readInt();
+        if (code == 0) return;
+        String msg = readString();
+        readException(code, msg);
+    }
+
+    /**
+     * Use this function for customized exception handling.
+     * customized method call this method for all unknown case
+     * @param code exception code
+     * @param msg exception message
+     */
+    public final void readException(int code, String msg) {
+        switch (code) {
+            case EX_SECURITY:
+                throw new SecurityException(msg);
+            case EX_BAD_PARCELABLE:
+                throw new BadParcelableException(msg);
+            case EX_ILLEGAL_ARGUMENT:
+                throw new IllegalArgumentException(msg);
+            case EX_NULL_POINTER:
+                throw new NullPointerException(msg);
+            case EX_ILLEGAL_STATE:
+                throw new IllegalStateException(msg);
+        }
+        throw new RuntimeException("Unknown exception code: " + code
+                + " msg " + msg);
+    }
+
+    /**
+     * Read an integer value from the parcel at the current dataPosition().
+     */
+    public final native int readInt();
+
+    /**
+     * Read a long integer value from the parcel at the current dataPosition().
+     */
+    public final native long readLong();
+
+    /**
+     * Read a floating point value from the parcel at the current
+     * dataPosition().
+     */
+    public final native float readFloat();
+
+    /**
+     * Read a double precision floating point value from the parcel at the
+     * current dataPosition().
+     */
+    public final native double readDouble();
+
+    /**
+     * Read a string value from the parcel at the current dataPosition().
+     */
+    public final native String readString();
+
+    /**
+     * Read an object from the parcel at the current dataPosition().
+     */
+    public final native IBinder readStrongBinder();
+
+    /**
+     * Read a FileDescriptor from the parcel at the current dataPosition().
+     */
+    public final ParcelFileDescriptor readFileDescriptor() {
+        FileDescriptor fd = internalReadFileDescriptor();
+        return fd != null ? new ParcelFileDescriptor(fd) : null;
+    }
+
+    private native FileDescriptor internalReadFileDescriptor();
+    /*package*/ static native FileDescriptor openFileDescriptor(String file,
+            int mode) throws FileNotFoundException;
+    /*package*/ static native void closeFileDescriptor(FileDescriptor desc)
+            throws IOException;
+
+    /**
+     * Read a byte value from the parcel at the current dataPosition().
+     */
+    public final byte readByte() {
+        return (byte)(readInt() & 0xff);
+    }
+
+    /**
+     * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
+     * been written with {@link #writeBundle}.  Read into an existing Map object
+     * from the parcel at the current dataPosition().
+     */
+    public final void readMap(Map outVal, ClassLoader loader) {
+        int N = readInt();
+        readMapInternal(outVal, N, loader);
+    }
+
+    /**
+     * Read into an existing List object from the parcel at the current
+     * dataPosition(), using the given class loader to load any enclosed
+     * Parcelables.  If it is null, the default class loader is used.
+     */
+    public final void readList(List outVal, ClassLoader loader) {
+        int N = readInt();
+        readListInternal(outVal, N, loader);
+    }
+
+    /**
+     * Please use {@link #readBundle(ClassLoader)} instead (whose data must have
+     * been written with {@link #writeBundle}.  Read and return a new HashMap
+     * object from the parcel at the current dataPosition(), using the given
+     * class loader to load any enclosed Parcelables.  Returns null if
+     * the previously written map object was null.
+     */
+    public final HashMap readHashMap(ClassLoader loader)
+    {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        HashMap m = new HashMap(N);
+        readMapInternal(m, N, loader);
+        return m;
+    }
+
+    /**
+     * Read and return a new Bundle object from the parcel at the current
+     * dataPosition().  Returns null if the previously written Bundle object was
+     * null.
+     */
+    public final Bundle readBundle() {
+        return readBundle(null);
+    }
+
+    /**
+     * Read and return a new Bundle object from the parcel at the current
+     * dataPosition(), using the given class loader to initialize the class
+     * loader of the Bundle for later retrieval of Parcelable objects.
+     * Returns null if the previously written Bundle object was null.
+     */
+    public final Bundle readBundle(ClassLoader loader) {
+        int offset = dataPosition();
+        int length = readInt();
+        if (length < 0) {
+            return null;
+        }
+        int magic = readInt();
+        if (magic != 0x4C444E42) {
+            //noinspection ThrowableInstanceNeverThrown
+            String st = Log.getStackTraceString(new RuntimeException());
+            Log.e("Bundle", "readBundle: bad magic number");
+            Log.e("Bundle", "readBundle: trace = " + st);
+        }
+
+        // Advance within this Parcel
+        setDataPosition(offset + length + 4);
+
+        Parcel p = new Parcel(0);
+        p.setDataPosition(0);
+        p.appendFrom(this, offset, length + 4);
+        p.setDataPosition(0);
+        final Bundle bundle = new Bundle(p);
+        if (loader != null) {
+            bundle.setClassLoader(loader);
+        }
+        return bundle;
+    }
+
+    /**
+     * Read and return a new Bundle object from the parcel at the current
+     * dataPosition().  Returns null if the previously written Bundle object was
+     * null.  The returned bundle will have its contents fully unpacked using
+     * the given ClassLoader.
+     */
+    /* package */ Bundle readBundleUnpacked(ClassLoader loader) {
+        int length = readInt();
+        if (length == -1) {
+            return null;
+        }
+        int magic = readInt();
+        if (magic != 0x4C444E42) {
+            //noinspection ThrowableInstanceNeverThrown
+            String st = Log.getStackTraceString(new RuntimeException());
+            Log.e("Bundle", "readBundleUnpacked: bad magic number");
+            Log.e("Bundle", "readBundleUnpacked: trace = " + st);
+        }
+        Bundle m = new Bundle(loader);
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        readMapInternal(m.mMap, N, loader);
+        return m;
+    }
+
+    /**
+     * Read and return a byte[] object from the parcel.
+     */
+    public final native byte[] createByteArray();
+
+    /**
+     * Read a byte[] object from the parcel and copy it into the
+     * given byte array.
+     */
+    public final void readByteArray(byte[] val) {
+        // TODO: make this a native method to avoid the extra copy.
+        byte[] ba = createByteArray();
+        if (ba.length == val.length) {
+           System.arraycopy(ba, 0, val, 0, ba.length);
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    /**
+     * Read and return a String[] object from the parcel.
+     * {@hide}
+     */
+    public final String[] readStringArray() {
+        String[] array = null;
+
+        int length = readInt();
+        if (length >= 0)
+        {
+            array = new String[length];
+
+            for (int i = 0 ; i < length ; i++)
+            {
+                array[i] = readString();
+            }
+        }
+
+        return array;
+    }
+
+    /**
+     * Read and return a new ArrayList object from the parcel at the current
+     * dataPosition().  Returns null if the previously written list object was
+     * null.  The given class loader will be used to load any enclosed
+     * Parcelables.
+     */
+    public final ArrayList readArrayList(ClassLoader loader) {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        ArrayList l = new ArrayList(N);
+        readListInternal(l, N, loader);
+        return l;
+    }
+
+    /**
+     * Read and return a new Object array from the parcel at the current
+     * dataPosition().  Returns null if the previously written array was
+     * null.  The given class loader will be used to load any enclosed
+     * Parcelables.
+     */
+    public final Object[] readArray(ClassLoader loader) {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        Object[] l = new Object[N];
+        readArrayInternal(l, N, loader);
+        return l;
+    }
+
+    /**
+     * Read and return a new SparseArray object from the parcel at the current
+     * dataPosition().  Returns null if the previously written list object was
+     * null.  The given class loader will be used to load any enclosed
+     * Parcelables.
+     */
+    public final SparseArray readSparseArray(ClassLoader loader) {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        SparseArray sa = new SparseArray(N);
+        readSparseArrayInternal(sa, N, loader);
+        return sa;
+    }
+
+    /**
+     * Read and return a new SparseBooleanArray object from the parcel at the current
+     * dataPosition().  Returns null if the previously written list object was
+     * null.
+     */
+    public final SparseBooleanArray readSparseBooleanArray() {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        SparseBooleanArray sa = new SparseBooleanArray(N);
+        readSparseBooleanArrayInternal(sa, N);
+        return sa;
+    }
+
+    /**
+     * Read and return a new ArrayList containing a particular object type from
+     * the parcel that was written with {@link #writeTypedList} at the
+     * current dataPosition().  Returns null if the
+     * previously written list object was null.  The list <em>must</em> have
+     * previously been written via {@link #writeTypedList} with the same object
+     * type.
+     *
+     * @return A newly created ArrayList containing objects with the same data
+     *         as those that were previously written.
+     *
+     * @see #writeTypedList
+     */
+    public final <T> ArrayList<T> createTypedArrayList(Parcelable.Creator<T> c) {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        ArrayList<T> l = new ArrayList<T>(N);
+        while (N > 0) {
+            if (readInt() != 0) {
+                l.add(c.createFromParcel(this));
+            } else {
+                l.add(null);
+            }
+            N--;
+        }
+        return l;
+    }
+
+    /**
+     * Read into the given List items containing a particular object type
+     * that were written with {@link #writeTypedList} at the
+     * current dataPosition().  The list <em>must</em> have
+     * previously been written via {@link #writeTypedList} with the same object
+     * type.
+     *
+     * @return A newly created ArrayList containing objects with the same data
+     *         as those that were previously written.
+     *
+     * @see #writeTypedList
+     */
+    public final <T> void readTypedList(List<T> list, Parcelable.Creator<T> c) {
+        int M = list.size();
+        int N = readInt();
+        int i = 0;
+        for (; i < M && i < N; i++) {
+            if (readInt() != 0) {
+                list.set(i, c.createFromParcel(this));
+            } else {
+                list.set(i, null);
+            }
+        }
+        for (; i<N; i++) {
+            if (readInt() != 0) {
+                list.add(c.createFromParcel(this));
+            } else {
+                list.add(null);
+            }
+        }
+        for (; i<M; i++) {
+            list.remove(N);
+        }
+    }
+
+    /**
+     * Read and return a new ArrayList containing String objects from
+     * the parcel that was written with {@link #writeStringList} at the
+     * current dataPosition().  Returns null if the
+     * previously written list object was null.
+     *
+     * @return A newly created ArrayList containing strings with the same data
+     *         as those that were previously written.
+     *
+     * @see #writeStringList
+     */
+    public final ArrayList<String> createStringArrayList() {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        ArrayList<String> l = new ArrayList<String>(N);
+        while (N > 0) {
+            l.add(readString());
+            N--;
+        }
+        return l;
+    }
+
+    /**
+     * Read and return a new ArrayList containing IBinder objects from
+     * the parcel that was written with {@link #writeBinderList} at the
+     * current dataPosition().  Returns null if the
+     * previously written list object was null.
+     *
+     * @return A newly created ArrayList containing strings with the same data
+     *         as those that were previously written.
+     *
+     * @see #writeBinderList
+     */
+    public final ArrayList<IBinder> createBinderArrayList() {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        ArrayList<IBinder> l = new ArrayList<IBinder>(N);
+        while (N > 0) {
+            l.add(readStrongBinder());
+            N--;
+        }
+        return l;
+    }
+
+    /**
+     * Read into the given List items String objects that were written with
+     * {@link #writeStringList} at the current dataPosition().
+     *
+     * @return A newly created ArrayList containing strings with the same data
+     *         as those that were previously written.
+     *
+     * @see #writeStringList
+     */
+    public final void readStringList(List<String> list) {
+        int M = list.size();
+        int N = readInt();
+        int i = 0;
+        for (; i < M && i < N; i++) {
+            list.set(i, readString());
+        }
+        for (; i<N; i++) {
+            list.add(readString());
+        }
+        for (; i<M; i++) {
+            list.remove(N);
+        }
+    }
+
+    /**
+     * Read into the given List items IBinder objects that were written with
+     * {@link #writeBinderList} at the current dataPosition().
+     *
+     * @return A newly created ArrayList containing strings with the same data
+     *         as those that were previously written.
+     *
+     * @see #writeBinderList
+     */
+    public final void readBinderList(List<IBinder> list) {
+        int M = list.size();
+        int N = readInt();
+        int i = 0;
+        for (; i < M && i < N; i++) {
+            list.set(i, readStrongBinder());
+        }
+        for (; i<N; i++) {
+            list.add(readStrongBinder());
+        }
+        for (; i<M; i++) {
+            list.remove(N);
+        }
+    }
+
+    /**
+     * Read and return a new array containing a particular object type from
+     * the parcel at the current dataPosition().  Returns null if the
+     * previously written array was null.  The array <em>must</em> have
+     * previously been written via {@link #writeTypedArray} with the same
+     * object type.
+     *
+     * @return A newly created array containing objects with the same data
+     *         as those that were previously written.
+     *
+     * @see #writeTypedArray
+     */
+    public final <T> T[] createTypedArray(Parcelable.Creator<T> c) {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        T[] l = c.newArray(N);
+        for (int i=0; i<N; i++) {
+            if (readInt() != 0) {
+                l[i] = c.createFromParcel(this);
+            }
+        }
+        return l;
+    }
+
+    public final <T> void readTypedArray(T[] val, Parcelable.Creator<T> c) {
+        int N = readInt();
+        if (N == val.length) {
+            for (int i=0; i<N; i++) {
+                if (readInt() != 0) {
+                    val[i] = c.createFromParcel(this);
+                } else {
+                    val[i] = null;
+                }
+            }
+        } else {
+            throw new RuntimeException("bad array lengths");
+        }
+    }
+
+    /**
+     * @deprecated
+     * @hide
+     */
+    @Deprecated
+    public final <T> T[] readTypedArray(Parcelable.Creator<T> c) {
+        return createTypedArray(c);
+    }
+
+    /**
+     * Write a heterogeneous array of Parcelable objects into the Parcel.
+     * Each object in the array is written along with its class name, so
+     * that the correct class can later be instantiated.  As a result, this
+     * has significantly more overhead than {@link #writeTypedArray}, but will
+     * correctly handle an array containing more than one type of object.
+     *
+     * @param value The array of objects to be written.
+     * @param parcelableFlags Contextual flags as per
+     * {@link Parcelable#writeToParcel(Parcel, int) Parcelable.writeToParcel()}.
+     *
+     * @see #writeTypedArray
+     */
+    public final <T extends Parcelable> void writeParcelableArray(T[] value,
+            int parcelableFlags) {
+        if (value != null) {
+            int N = value.length;
+            writeInt(N);
+            for (int i=0; i<N; i++) {
+                writeParcelable(value[i], parcelableFlags);
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    /**
+     * Read a typed object from a parcel.  The given class loader will be
+     * used to load any enclosed Parcelables.  If it is null, the default class
+     * loader will be used.
+     */
+    public final Object readValue(ClassLoader loader) {
+        int type = readInt();
+
+        switch (type) {
+        case VAL_NULL:
+            return null;
+
+        case VAL_STRING:
+            return readString();
+
+        case VAL_INTEGER:
+            return readInt();
+
+        case VAL_MAP:
+            return readHashMap(loader);
+
+        case VAL_PARCELABLE:
+            return readParcelable(loader);
+
+        case VAL_SHORT:
+            return (short) readInt();
+
+        case VAL_LONG:
+            return readLong();
+
+        case VAL_FLOAT:
+            return readFloat();
+
+        case VAL_DOUBLE:
+            return readDouble();
+
+        case VAL_BOOLEAN:
+            return readInt() == 1;
+
+        case VAL_CHARSEQUENCE:
+            return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(this);
+
+        case VAL_LIST:
+            return readArrayList(loader);
+
+        case VAL_BOOLEANARRAY:
+            return createBooleanArray();        
+
+        case VAL_BYTEARRAY:
+            return createByteArray();
+
+        case VAL_STRINGARRAY:
+            return readStringArray();
+
+        case VAL_IBINDER:
+            return readStrongBinder();
+
+        case VAL_OBJECTARRAY:
+            return readArray(loader);
+
+        case VAL_INTARRAY:
+            return createIntArray();
+
+        case VAL_LONGARRAY:
+            return createLongArray();
+
+        case VAL_BYTE:
+            return readByte();
+
+        case VAL_SERIALIZABLE:
+            return readSerializable();
+
+        case VAL_PARCELABLEARRAY:
+            return readParcelableArray(loader);
+
+        case VAL_SPARSEARRAY:
+            return readSparseArray(loader);
+
+        case VAL_SPARSEBOOLEANARRAY:
+            return readSparseBooleanArray();
+
+        case VAL_BUNDLE:
+            return readBundle(loader); // loading will be deferred
+
+        default:
+            int off = dataPosition() - 4;
+            throw new RuntimeException(
+                "Parcel " + this + ": Unmarshalling unknown type code " + type + " at offset " + off);
+        }
+    }
+
+    /**
+     * Read and return a new Parcelable from the parcel.  The given class loader
+     * will be used to load any enclosed Parcelables.  If it is null, the default
+     * class loader will be used.
+     * @param loader A ClassLoader from which to instantiate the Parcelable
+     * object, or null for the default class loader.
+     * @return Returns the newly created Parcelable, or null if a null
+     * object has been written.
+     * @throws BadParcelableException Throws BadParcelableException if there
+     * was an error trying to instantiate the Parcelable.
+     */
+    public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
+        String name = readString();
+        if (name == null) {
+            return null;
+        }
+        Parcelable.Creator<T> creator;
+        synchronized (mCreators) {
+            HashMap<String,Parcelable.Creator> map = mCreators.get(loader);
+            if (map == null) {
+                map = new HashMap<String,Parcelable.Creator>();
+                mCreators.put(loader, map);
+            }
+            creator = map.get(name);
+            if (creator == null) {
+                try {
+                    Class c = loader == null ?
+                        Class.forName(name) : Class.forName(name, true, loader);
+                    Field f = c.getField("CREATOR");
+                    creator = (Parcelable.Creator)f.get(null);
+                }
+                catch (IllegalAccessException e) {
+                    Log.e("Parcel", "Class not found when unmarshalling: "
+                                        + name + ", e: " + e);
+                    throw new BadParcelableException(
+                            "IllegalAccessException when unmarshalling: " + name);
+                }
+                catch (ClassNotFoundException e) {
+                    Log.e("Parcel", "Class not found when unmarshalling: "
+                                        + name + ", e: " + e);
+                    throw new BadParcelableException(
+                            "ClassNotFoundException when unmarshalling: " + name);
+                }
+                catch (ClassCastException e) {
+                    throw new BadParcelableException("Parcelable protocol requires a "
+                                        + "Parcelable.Creator object called "
+                                        + " CREATOR on class " + name);
+                }
+                catch (NoSuchFieldException e) {
+                    throw new BadParcelableException("Parcelable protocol requires a "
+                                        + "Parcelable.Creator object called "
+                                        + " CREATOR on class " + name);
+                }
+                if (creator == null) {
+                    throw new BadParcelableException("Parcelable protocol requires a "
+                                        + "Parcelable.Creator object called "
+                                        + " CREATOR on class " + name);
+                }
+
+                map.put(name, creator);
+            }
+        }
+
+        return creator.createFromParcel(this);
+    }
+
+    /**
+     * Read and return a new Parcelable array from the parcel.
+     * The given class loader will be used to load any enclosed
+     * Parcelables.
+     * @return the Parcelable array, or null if the array is null
+     */
+    public final Parcelable[] readParcelableArray(ClassLoader loader) {
+        int N = readInt();
+        if (N < 0) {
+            return null;
+        }
+        Parcelable[] p = new Parcelable[N];
+        for (int i = 0; i < N; i++) {
+            p[i] = (Parcelable) readParcelable(loader);
+        }
+        return p;
+    }
+
+    /**
+     * Read and return a new Serializable object from the parcel.
+     * @return the Serializable object, or null if the Serializable name
+     * wasn't found in the parcel.
+     */
+    public final Serializable readSerializable() {
+        String name = readString();
+        if (name == null) {
+            // For some reason we were unable to read the name of the Serializable (either there
+            // is nothing left in the Parcel to read, or the next value wasn't a String), so
+            // return null, which indicates that the name wasn't found in the parcel.
+            return null;
+        }
+
+        byte[] serializedData = createByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
+        try {
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return (Serializable) ois.readObject();
+        } catch (IOException ioe) {
+            throw new RuntimeException("Parcelable encountered " +
+                "IOException reading a Serializable object (name = " + name +
+                ")", ioe);
+        } catch (ClassNotFoundException cnfe) {
+            throw new RuntimeException("Parcelable encountered" +
+                "ClassNotFoundException reading a Serializable object (name = "
+                + name + ")", cnfe);
+        }
+    }
+
+    // Cache of previously looked up CREATOR.createFromParcel() methods for
+    // particular classes.  Keys are the names of the classes, values are
+    // Method objects.
+    private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>
+        mCreators = new HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>();
+
+    static protected final Parcel obtain(int obj) {
+        final Parcel[] pool = sHolderPool;
+        synchronized (pool) {
+            Parcel p;
+            for (int i=0; i<POOL_SIZE; i++) {
+                p = pool[i];
+                if (p != null) {
+                    pool[i] = null;
+                    if (DEBUG_RECYCLE) {
+                        p.mStack = new RuntimeException();
+                    }
+                    p.init(obj);
+                    return p;
+                }
+            }
+        }
+        return new Parcel(obj);
+    }
+
+    private Parcel(int obj) {
+        if (DEBUG_RECYCLE) {
+            mStack = new RuntimeException();
+        }
+        //Log.i("Parcel", "Initializing obj=0x" + Integer.toHexString(obj), mStack);
+        init(obj);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        if (DEBUG_RECYCLE) {
+            if (mStack != null) {
+                Log.w("Parcel", "Client did not call Parcel.recycle()", mStack);
+            }
+        }
+        destroy();
+    }
+
+    private native void freeBuffer();
+    private native void init(int obj);
+    private native void destroy();
+
+    private void readMapInternal(Map outVal, int N,
+        ClassLoader loader) {
+        while (N > 0) {
+            Object key = readValue(loader);
+            Object value = readValue(loader);
+            outVal.put(key, value);
+            N--;
+        }
+    }
+
+    private void readListInternal(List outVal, int N,
+        ClassLoader loader) {
+        while (N > 0) {
+            Object value = readValue(loader);
+            //Log.d("Parcel", "Unmarshalling value=" + value);
+            outVal.add(value);
+            N--;
+        }
+    }
+
+    private void readArrayInternal(Object[] outVal, int N,
+        ClassLoader loader) {
+        for (int i = 0; i < N; i++) {
+            Object value = readValue(loader);
+            //Log.d("Parcel", "Unmarshalling value=" + value);
+            outVal[i] = value;
+        }
+    }
+
+    private void readSparseArrayInternal(SparseArray outVal, int N,
+        ClassLoader loader) {
+        while (N > 0) {
+            int key = readInt();
+            Object value = readValue(loader);
+            //Log.i("Parcel", "Unmarshalling key=" + key + " value=" + value);
+            outVal.append(key, value);
+            N--;
+        }
+    }
+
+
+    private void readSparseBooleanArrayInternal(SparseBooleanArray outVal, int N) {
+        while (N > 0) {
+            int key = readInt();
+            boolean value = this.readByte() == 1;
+            //Log.i("Parcel", "Unmarshalling key=" + key + " value=" + value);
+            outVal.append(key, value);
+            N--;
+        }
+    }
+}
diff --git a/core/java/android/os/ParcelFileDescriptor.aidl b/core/java/android/os/ParcelFileDescriptor.aidl
new file mode 100644
index 0000000..5857aae
--- /dev/null
+++ b/core/java/android/os/ParcelFileDescriptor.aidl
@@ -0,0 +1,20 @@
+/* //device/java/android/android/os/ParcelFileDescriptor.aidl
+**
+** Copyright 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;
+
+parcelable ParcelFileDescriptor;
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
new file mode 100644
index 0000000..3fcb18e
--- /dev/null
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2006 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 java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+
+/**
+ * The FileDescriptor returned by {@link Parcel#readFileDescriptor}, allowing
+ * you to close it when done with it.
+ */
+public class ParcelFileDescriptor implements Parcelable {
+    private final FileDescriptor mFileDescriptor;
+    private boolean mClosed;
+    //this field is to create wrapper for ParcelFileDescriptor using another
+    //PartialFileDescriptor but avoid invoking close twice
+    //consider ParcelFileDescriptor A(fileDescriptor fd),  ParcelFileDescriptor B(A)
+    //in this particular case fd.close might be invoked twice.
+    private final ParcelFileDescriptor mParcelDescriptor;
+    
+    /**
+     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
+     * and this file doesn't already exist, then create the file with
+     * permissions such that any application can read it.
+     */
+    public static final int MODE_WORLD_READABLE = 0x00000001;
+    
+    /**
+     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
+     * and this file doesn't already exist, then create the file with
+     * permissions such that any application can write it.
+     */
+    public static final int MODE_WORLD_WRITEABLE = 0x00000002;
+    
+    /**
+     * For use with {@link #open}: open the file with read-only access.
+     */
+    public static final int MODE_READ_ONLY = 0x10000000;
+    
+    /**
+     * For use with {@link #open}: open the file with write-only access.
+     */
+    public static final int MODE_WRITE_ONLY = 0x20000000;
+    
+    /**
+     * For use with {@link #open}: open the file with read and write access.
+     */
+    public static final int MODE_READ_WRITE = 0x30000000;
+    
+    /**
+     * For use with {@link #open}: create the file if it doesn't already exist.
+     */
+    public static final int MODE_CREATE = 0x08000000;
+    
+    /**
+     * For use with {@link #open}: erase contents of file when opening.
+     */
+    public static final int MODE_TRUNCATE = 0x04000000;
+    
+    /**
+     * For use with {@link #open}: append to end of file while writing.
+     */
+    public static final int MODE_APPEND = 0x02000000;
+    
+    /**
+     * Create a new ParcelFileDescriptor accessing a given file.
+     * 
+     * @param file The file to be opened.
+     * @param mode The desired access mode, must be one of
+     * {@link #MODE_READ_ONLY}, {@link #MODE_WRITE_ONLY}, or
+     * {@link #MODE_READ_WRITE}; may also be any combination of
+     * {@link #MODE_CREATE}, {@link #MODE_TRUNCATE},
+     * {@link #MODE_WORLD_READABLE}, and {@link #MODE_WORLD_WRITEABLE}.
+     * 
+     * @return Returns a new ParcelFileDescriptor pointing to the given
+     * file.
+     * 
+     * @throws FileNotFoundException Throws FileNotFoundException if the given
+     * file does not exist or can not be opened with the requested mode.
+     */
+    public static ParcelFileDescriptor open(File file, int mode)
+            throws FileNotFoundException {
+        String path = file.getPath();
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkRead(path);
+            if ((mode&MODE_WRITE_ONLY) != 0) {
+                security.checkWrite(path);
+            }
+        }
+        
+        if ((mode&MODE_READ_WRITE) == 0) {
+            throw new IllegalArgumentException(
+                    "Must specify MODE_READ_ONLY, MODE_WRITE_ONLY, or MODE_READ_WRITE");
+        }
+        
+        FileDescriptor fd = Parcel.openFileDescriptor(path, mode);
+        return new ParcelFileDescriptor(fd);
+    }
+
+    /**
+     * Create a new ParcelFileDescriptor from the specified Socket.
+     *
+     * @param socket The Socket whose FileDescriptor is used to create
+     *               a new ParcelFileDescriptor.
+     *
+     * @return A new ParcelFileDescriptor with the FileDescriptor of the
+     *         specified Socket.
+     */
+    public static ParcelFileDescriptor fromSocket(Socket socket) {
+        FileDescriptor fd = getFileDescriptorFromSocket(socket);
+        return new ParcelFileDescriptor(fd);
+    }
+
+    // Extracts the file descriptor from the specified socket and returns it untouched
+    private static native FileDescriptor getFileDescriptorFromSocket(Socket socket);
+
+    /**
+     * Retrieve the actual FileDescriptor associated with this object.
+     * 
+     * @return Returns the FileDescriptor associated with this object.
+     */
+    public FileDescriptor getFileDescriptor() {
+        return mFileDescriptor;
+    }
+    
+    /**
+     * Return the total size of the file representing this fd, as determined
+     * by stat().  Returns -1 if the fd is not a file.
+     */
+    public native long getStatSize();
+    
+    /**
+     * This is needed for implementing AssetFileDescriptor.AutoCloseOutputStream,
+     * and I really don't think we want it to be public.
+     * @hide
+     */
+    public native long seekTo(long pos);
+    
+    /**
+     * Close the ParcelFileDescriptor. This implementation closes the underlying
+     * OS resources allocated to represent this stream.
+     * 
+     * @throws IOException
+     *             If an error occurs attempting to close this ParcelFileDescriptor.
+     */
+    public void close() throws IOException {
+        mClosed = true;
+        if (mParcelDescriptor != null) {
+            // If this is a proxy to another file descriptor, just call through to its
+            // close method.
+            mParcelDescriptor.close();
+        } else {
+            Parcel.closeFileDescriptor(mFileDescriptor);
+        }
+    }
+    
+    /**
+     * An InputStream you can create on a ParcelFileDescriptor, which will
+     * take care of calling {@link ParcelFileDescriptor#close
+     * ParcelFileDescritor.close()} for you when the stream is closed.
+     */
+    public static class AutoCloseInputStream extends FileInputStream {
+        private final ParcelFileDescriptor mFd;
+        
+        public AutoCloseInputStream(ParcelFileDescriptor fd) {
+            super(fd.getFileDescriptor());
+            mFd = fd;
+        }
+
+        @Override
+        public void close() throws IOException {
+            mFd.close();
+        }
+    }
+    
+    /**
+     * An OutputStream you can create on a ParcelFileDescriptor, which will
+     * take care of calling {@link ParcelFileDescriptor#close
+     * ParcelFileDescritor.close()} for you when the stream is closed.
+     */
+    public static class AutoCloseOutputStream extends FileOutputStream {
+        private final ParcelFileDescriptor mFd;
+        
+        public AutoCloseOutputStream(ParcelFileDescriptor fd) {
+            super(fd.getFileDescriptor());
+            mFd = fd;
+        }
+
+        @Override
+        public void close() throws IOException {
+            mFd.close();
+        }
+    }
+    
+    @Override
+    public String toString() {
+        return "{ParcelFileDescriptor: " + mFileDescriptor + "}";
+    }
+    
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (!mClosed) {
+                close();
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+    
+    public ParcelFileDescriptor(ParcelFileDescriptor descriptor) {
+        super();
+        mParcelDescriptor = descriptor;
+        mFileDescriptor = mParcelDescriptor.mFileDescriptor;
+    }
+    
+    /*package */ParcelFileDescriptor(FileDescriptor descriptor) {
+        super();
+        mFileDescriptor = descriptor;
+        mParcelDescriptor = null;
+    }
+    
+    /* Parcelable interface */
+    public int describeContents() {
+        return Parcelable.CONTENTS_FILE_DESCRIPTOR;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeFileDescriptor(mFileDescriptor);
+        if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
+            try {
+                close();
+            } catch (IOException e) {
+                // Empty
+            }
+        }
+    }
+
+    public static final Parcelable.Creator<ParcelFileDescriptor> CREATOR
+            = new Parcelable.Creator<ParcelFileDescriptor>() {
+        public ParcelFileDescriptor createFromParcel(Parcel in) {
+            return in.readFileDescriptor();
+        }
+        public ParcelFileDescriptor[] newArray(int size) {
+            return new ParcelFileDescriptor[size];
+        }
+    };
+
+}
diff --git a/core/java/android/os/ParcelFormatException.java b/core/java/android/os/ParcelFormatException.java
new file mode 100644
index 0000000..8b6fda0
--- /dev/null
+++ b/core/java/android/os/ParcelFormatException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * The contents of a Parcel (usually during unmarshalling) does not
+ * contain the expected data.
+ */
+public class ParcelFormatException extends RuntimeException {
+    public ParcelFormatException() {
+        super();
+    }
+
+    public ParcelFormatException(String reason) {
+        super(reason);
+    }
+}
diff --git a/core/java/android/os/Parcelable.java b/core/java/android/os/Parcelable.java
new file mode 100644
index 0000000..aee1e0b
--- /dev/null
+++ b/core/java/android/os/Parcelable.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * Interface for classes whose instances can be written to
+ * and restored from a {@link Parcel}.  Classes implementing the Parcelable
+ * interface must also have a static field called <code>CREATOR</code>, which
+ * is an object implementing the {@link Parcelable.Creator Parcelable.Creator}
+ * interface.
+ * 
+ * <p>A typical implementation of Parcelable is:</p>
+ * 
+ * <pre>
+ * public class MyParcelable implements Parcelable {
+ *     private int mData;
+ *     
+ *     public void writeToParcel(Parcel out, int flags) {
+ *         out.writeInt(mData);
+ *     }
+ *
+ *     public static final Parcelable.Creator<MyParcelable> CREATOR
+ *             = new Parcelable.Creator<MyParcelable>() {
+ *         public MyParcelable createFromParcel(Parcel in) {
+ *             return new MyParcelable(in);
+ *         }
+ *
+ *         public MyParcelable[] newArray(int size) {
+ *             return new MyParcelable[size];
+ *         }
+ *     }
+ *     
+ *     private MyParcelable(Parcel in) {
+ *         mData = in.readInt();
+ *     }
+ * }</pre>
+ */
+public interface Parcelable {
+    /**
+     * Flag for use with {@link #writeToParcel}: the object being written
+     * is a return value, that is the result of a function such as
+     * "<code>Parcelable someFunction()</code>",
+     * "<code>void someFunction(out Parcelable)</code>", or
+     * "<code>void someFunction(inout Parcelable)</code>".  Some implementations
+     * may want to release resources at this point.
+     */
+    public static final int PARCELABLE_WRITE_RETURN_VALUE = 0x0001;
+    
+    /**
+     * Bit masks for use with {@link #describeContents}: each bit represents a
+     * kind of object considered to have potential special significance when
+     * marshalled.
+     */
+    public static final int CONTENTS_FILE_DESCRIPTOR = 0x0001;
+    
+    /**
+     * Describe the kinds of special objects contained in this Parcelable's
+     * marshalled representation.
+     *  
+     * @return a bitmask indicating the set of special object types marshalled
+     * by the Parcelable.
+     */
+    public int describeContents();
+    
+    /**
+     * Flatten this object in to a Parcel.
+     * 
+     * @param dest The Parcel in which the object should be written.
+     * @param flags Additional flags about how the object should be written.
+     * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+     */
+    public void writeToParcel(Parcel dest, int flags);
+
+    /**
+     * Interface that must be implemented and provided as a public CREATOR
+     * field that generates instances of your Parcelable class from a Parcel.
+     */
+    public interface Creator<T> {
+        /**
+         * Create a new instance of the Parcelable class, instantiating it
+         * from the given Parcel whose data had previously been written by
+         * {@link Parcelable#writeToParcel Parcelable.writeToParcel()}.
+         * 
+         * @param source The Parcel to read the object's data from.
+         * @return Returns a new instance of the Parcelable class.
+         */
+        public T createFromParcel(Parcel source);
+        
+        /**
+         * Create a new array of the Parcelable class.
+         * 
+         * @param size Size of the array.
+         * @return Returns an array of the Parcelable class, with every entry
+         * initialized to null.
+         */
+        public T[] newArray(int size);
+    }
+}
diff --git a/core/java/android/os/PatternMatcher.aidl b/core/java/android/os/PatternMatcher.aidl
new file mode 100644
index 0000000..86309f1
--- /dev/null
+++ b/core/java/android/os/PatternMatcher.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2008 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;
+
+parcelable PatternMatcher;
diff --git a/core/java/android/os/PatternMatcher.java b/core/java/android/os/PatternMatcher.java
new file mode 100644
index 0000000..56dc837
--- /dev/null
+++ b/core/java/android/os/PatternMatcher.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2008 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;
+
+/**
+ * A simple pattern matcher, which is safe to use on untrusted data: it does
+ * not provide full reg-exp support, only simple globbing that can not be
+ * used maliciously.
+ */
+public class PatternMatcher implements Parcelable {
+    /**
+     * Pattern type: the given pattern must exactly match the string it is
+     * tested against.
+     */
+    public static final int PATTERN_LITERAL = 0;
+    
+    /**
+     * Pattern type: the given pattern must match the
+     * beginning of the string it is tested against.
+     */
+    public static final int PATTERN_PREFIX = 1;
+    
+    /**
+     * Pattern type: the given pattern is interpreted with a
+     * simple glob syntax for matching against the string it is tested against.
+     * In this syntax, you can use the '*' character to match against zero or
+     * more occurrences of the character immediately before.  If the
+     * character before it is '.' it will match any character.  The character
+     * '\' can be used as an escape.  This essentially provides only the '*'
+     * wildcard part of a normal regexp. 
+     */
+    public static final int PATTERN_SIMPLE_GLOB = 2;
+    
+    private final String mPattern;
+    private final int mType;
+    
+    public PatternMatcher(String pattern, int type) {
+        mPattern = pattern;
+        mType = type;
+    }
+
+    public final String getPath() {
+        return mPattern;
+    }
+    
+    public final int getType() {
+        return mType;
+    }
+    
+    public boolean match(String str) {
+        return matchPattern(mPattern, str, mType);
+    }
+
+    public String toString() {
+        String type = "? ";
+        switch (mType) {
+            case PATTERN_LITERAL:
+                type = "LITERAL: ";
+                break;
+            case PATTERN_PREFIX:
+                type = "PREFIX: ";
+                break;
+            case PATTERN_SIMPLE_GLOB:
+                type = "GLOB: ";
+                break;
+        }
+        return "PatternMatcher{" + type + mPattern + "}";
+    }
+    
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mPattern);
+        dest.writeInt(mType);
+    }
+    
+    public PatternMatcher(Parcel src) {
+        mPattern = src.readString();
+        mType = src.readInt();
+    }
+    
+    public static final Parcelable.Creator<PatternMatcher> CREATOR
+            = new Parcelable.Creator<PatternMatcher>() {
+        public PatternMatcher createFromParcel(Parcel source) {
+            return new PatternMatcher(source);
+        }
+
+        public PatternMatcher[] newArray(int size) {
+            return new PatternMatcher[size];
+        }
+    };
+    
+    static boolean matchPattern(String pattern, String match, int type) {
+        if (match == null) return false;
+        if (type == PATTERN_LITERAL) {
+            return pattern.equals(match);
+        } if (type == PATTERN_PREFIX) {
+            return match.startsWith(pattern);
+        } else if (type != PATTERN_SIMPLE_GLOB) {
+            return false;
+        }
+        
+        final int NP = pattern.length();
+        if (NP <= 0) {
+            return match.length() <= 0;
+        }
+        final int NM = match.length();
+        int ip = 0, im = 0;
+        char nextChar = pattern.charAt(0);
+        while ((ip<NP) && (im<NM)) {
+            char c = nextChar;
+            ip++;
+            nextChar = ip < NP ? pattern.charAt(ip) : 0;
+            final boolean escaped = (c == '\\');
+            if (escaped) {
+                c = nextChar;
+                ip++;
+                nextChar = ip < NP ? pattern.charAt(ip) : 0;
+            }
+            if (nextChar == '*') {
+                if (!escaped && c == '.') {
+                    if (ip >= (NP-1)) {
+                        // at the end with a pattern match, so
+                        // all is good without checking!
+                        return true;
+                    }
+                    ip++;
+                    nextChar = pattern.charAt(ip);
+                    // Consume everything until the next character in the
+                    // pattern is found.
+                    if (nextChar == '\\') {
+                        ip++;
+                        nextChar = ip < NP ? pattern.charAt(ip) : 0;
+                    }
+                    do {
+                        if (match.charAt(im) == nextChar) {
+                            break;
+                        }
+                        im++;
+                    } while (im < NM);
+                    if (im == NM) {
+                        // Whoops, the next character in the pattern didn't
+                        // exist in the match.
+                        return false;
+                    }
+                    ip++;
+                    nextChar = ip < NP ? pattern.charAt(ip) : 0;
+                    im++;
+                } else {
+                    // Consume only characters matching the one before '*'.
+                    do {
+                        if (match.charAt(im) != c) {
+                            break;
+                        }
+                        im++;
+                    } while (im < NM);
+                    ip++;
+                    nextChar = ip < NP ? pattern.charAt(ip) : 0;
+                }
+            } else {
+                if (c != '.' && match.charAt(im) != c) return false;
+                im++;
+            }
+        }
+        
+        if (ip >= NP && im >= NM) {
+            // Reached the end of both strings, all is good!
+            return true;
+        }
+        
+        // One last check: we may have finished the match string, but still
+        // have a '.*' at the end of the pattern, which should still count
+        // as a match.
+        if (ip == NP-2 && pattern.charAt(ip) == '.'
+            && pattern.charAt(ip+1) == '*') {
+            return true;
+        }
+        
+        return false;
+    }
+}
diff --git a/core/java/android/os/Power.java b/core/java/android/os/Power.java
new file mode 100644
index 0000000..b53e227
--- /dev/null
+++ b/core/java/android/os/Power.java
@@ -0,0 +1,130 @@
+/*
+ * 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 java.io.IOException;
+
+/**
+ * Class that provides access to some of the power management functions.
+ *
+ * {@hide}
+ */
+public class Power
+{
+    // can't instantiate this class
+    private Power()
+    {
+    }
+
+    /**
+     * Wake lock that ensures that the CPU is running.  The screen might
+     * not be on.
+     */
+    public static final int PARTIAL_WAKE_LOCK = 1;
+
+    /**
+     * Wake lock that ensures that the screen is on.
+     */
+    public static final int FULL_WAKE_LOCK = 2;
+
+    public static native void acquireWakeLock(int lock, String id);
+    public static native void releaseWakeLock(String id);
+
+    /**
+     * Flag to turn on and off the keyboard light.
+     */
+    public static final int KEYBOARD_LIGHT = 0x00000001;
+
+    /**
+     * Flag to turn on and off the screen backlight.
+     */
+    public static final int SCREEN_LIGHT = 0x00000002;
+
+    /**
+     * Flag to turn on and off the button backlight.
+     */
+    public static final int BUTTON_LIGHT = 0x00000004;
+
+    /**
+     * Flags to turn on and off all the backlights.
+     */
+    public static final int ALL_LIGHTS = (KEYBOARD_LIGHT|SCREEN_LIGHT|BUTTON_LIGHT);
+
+    /**
+     * Brightness value for fully off
+     */
+    public static final int BRIGHTNESS_OFF = 0;
+
+    /**
+     * Brightness value for dim backlight
+     */
+    public static final int BRIGHTNESS_DIM = 20;
+
+    /**
+     * Brightness value for fully on
+     */
+    public static final int BRIGHTNESS_ON = 255;
+
+    /**
+     * Brightness value to use when battery is low
+     */
+    public static final int BRIGHTNESS_LOW_BATTERY = 10;
+
+    /**
+     * Threshold for BRIGHTNESS_LOW_BATTERY (percentage)
+     * Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD
+     */
+    public static final int LOW_BATTERY_THRESHOLD = 10;
+
+    /**
+     * Set the brightness for one or more lights
+     *
+     * @param mask flags indicating which lights to change brightness
+     * @param brightness new brightness value (0 = off, 255 = fully bright)
+     */
+    public static native int setLightBrightness(int mask, int brightness);
+
+    /**
+     * Turn the screen on or off
+     *
+     * @param on Whether you want the screen on or off
+     */
+    public static native int setScreenState(boolean on);
+
+    public static native int setLastUserActivityTimeout(long ms);
+
+    /**
+     * Turn the device off.
+     *
+     * This method is considered deprecated in favor of
+     * {@link android.policy.ShutdownThread.shutdownAfterDisablingRadio()}.
+     *
+     * @deprecated
+     * @hide
+     */
+    @Deprecated
+    public static native void shutdown();
+
+    /**
+     * Reboot the device.
+     * @param reason code to pass to the kernel (e.g. "recovery"), or null.
+     *
+     * @throws IOException if reboot fails for some reason (eg, lack of
+     *         permission)
+     */
+    public static native void reboot(String reason) throws IOException;
+}
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;
+}
+
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
new file mode 100644
index 0000000..cd86fbe
--- /dev/null
+++ b/core/java/android/os/Process.java
@@ -0,0 +1,706 @@
+/*
+ * Copyright (C) 2006 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.net.LocalSocketAddress;
+import android.net.LocalSocket;
+import android.util.Log;
+import dalvik.system.Zygote;
+
+import java.io.BufferedWriter;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+
+/*package*/ class ZygoteStartFailedEx extends Exception {
+    /**
+     * Something prevented the zygote process startup from happening normally
+     */
+
+    ZygoteStartFailedEx() {};
+    ZygoteStartFailedEx(String s) {super(s);}
+    ZygoteStartFailedEx(Throwable cause) {super(cause);}
+}
+
+/**
+ * Tools for managing OS processes.
+ */
+public class Process {
+    private static final String LOG_TAG = "Process";
+
+    private static final String ZYGOTE_SOCKET = "zygote";
+
+    /**
+     * Name of a process for running the platform's media services.
+     * {@hide}
+     */
+    public static final String ANDROID_SHARED_MEDIA = "com.android.process.media";
+
+    /**
+     * Name of the process that Google content providers can share.
+     * {@hide}
+     */
+    public static final String GOOGLE_SHARED_APP_CONTENT = "com.google.process.content";
+
+    /**
+     * Defines the UID/GID under which system code runs.
+     */
+    public static final int SYSTEM_UID = 1000;
+
+    /**
+     * Defines the UID/GID under which the telephony code runs.
+     */
+    public static final int PHONE_UID = 1001;
+
+    /**
+     * Defines the start of a range of UIDs (and GIDs), going from this
+     * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
+     * to applications.
+     */
+    public static final int FIRST_APPLICATION_UID = 10000;
+    /**
+     * Last of application-specific UIDs starting at
+     * {@link #FIRST_APPLICATION_UID}.
+     */
+    public static final int LAST_APPLICATION_UID = 99999;
+
+    /**
+     * Defines a secondary group id for access to the bluetooth hardware.
+     */
+    public static final int BLUETOOTH_GID = 2000;
+    
+    /**
+     * Standard priority of application threads.
+     * Use with {@link #setThreadPriority(int)} and
+     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
+     * {@link java.lang.Thread} class.
+     */
+    public static final int THREAD_PRIORITY_DEFAULT = 0;
+
+    /*
+     * ***************************************
+     * ** Keep in sync with utils/threads.h **
+     * ***************************************
+     */
+    
+    /**
+     * Lowest available thread priority.  Only for those who really, really
+     * don't want to run if anything else is happening.
+     * Use with {@link #setThreadPriority(int)} and
+     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
+     * {@link java.lang.Thread} class.
+     */
+    public static final int THREAD_PRIORITY_LOWEST = 19;
+    
+    /**
+     * Standard priority background threads.  This gives your thread a slightly
+     * lower than normal priority, so that it will have less chance of impacting
+     * the responsiveness of the user interface.
+     * Use with {@link #setThreadPriority(int)} and
+     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
+     * {@link java.lang.Thread} class.
+     */
+    public static final int THREAD_PRIORITY_BACKGROUND = 10;
+    
+    /**
+     * Standard priority of threads that are currently running a user interface
+     * that the user is interacting with.  Applications can not normally
+     * change to this priority; the system will automatically adjust your
+     * application threads as the user moves through the UI.
+     * Use with {@link #setThreadPriority(int)} and
+     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
+     * {@link java.lang.Thread} class.
+     */
+    public static final int THREAD_PRIORITY_FOREGROUND = -2;
+    
+    /**
+     * Standard priority of system display threads, involved in updating
+     * the user interface.  Applications can not
+     * normally change to this priority.
+     * Use with {@link #setThreadPriority(int)} and
+     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
+     * {@link java.lang.Thread} class.
+     */
+    public static final int THREAD_PRIORITY_DISPLAY = -4;
+    
+    /**
+     * Standard priority of the most important display threads, for compositing
+     * the screen and retrieving input events.  Applications can not normally
+     * change to this priority.
+     * Use with {@link #setThreadPriority(int)} and
+     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
+     * {@link java.lang.Thread} class.
+     */
+    public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8;
+
+    /**
+     * Standard priority of audio threads.  Applications can not normally
+     * change to this priority.
+     * Use with {@link #setThreadPriority(int)} and
+     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
+     * {@link java.lang.Thread} class.
+     */
+    public static final int THREAD_PRIORITY_AUDIO = -16;
+
+    /**
+     * Standard priority of the most important audio threads.
+     * Applications can not normally change to this priority.
+     * Use with {@link #setThreadPriority(int)} and
+     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
+     * {@link java.lang.Thread} class.
+     */
+    public static final int THREAD_PRIORITY_URGENT_AUDIO = -19;
+
+    /**
+     * Minimum increment to make a priority more favorable.
+     */
+    public static final int THREAD_PRIORITY_MORE_FAVORABLE = -1;
+
+    /**
+     * Minimum increment to make a priority less favorable.
+     */
+    public static final int THREAD_PRIORITY_LESS_FAVORABLE = +1;
+
+    public static final int SIGNAL_QUIT = 3;
+    public static final int SIGNAL_KILL = 9;
+    public static final int SIGNAL_USR1 = 10;
+    
+    // State for communicating with zygote process
+
+    static LocalSocket sZygoteSocket;
+    static DataInputStream sZygoteInputStream;
+    static BufferedWriter sZygoteWriter;
+
+    /** true if previous zygote open failed */
+    static boolean sPreviousZygoteOpenFailed;
+
+    /**
+     * Start a new process.
+     * 
+     * <p>If processes are enabled, a new process is created and the
+     * static main() function of a <var>processClass</var> is executed there.
+     * The process will continue running after this function returns.
+     * 
+     * <p>If processes are not enabled, a new thread in the caller's
+     * process is created and main() of <var>processClass</var> called there.
+     * 
+     * <p>The niceName parameter, if not an empty string, is a custom name to
+     * give to the process instead of using processClass.  This allows you to
+     * make easily identifyable processes even if you are using the same base
+     * <var>processClass</var> to start them.
+     * 
+     * @param processClass The class to use as the process's main entry
+     *                     point.
+     * @param niceName A more readable name to use for the process.
+     * @param uid The user-id under which the process will run.
+     * @param gid The group-id under which the process will run.
+     * @param gids Additional group-ids associated with the process.
+     * @param enableDebugger True if debugging should be enabled for this process.
+     * @param zygoteArgs Additional arguments to supply to the zygote process.
+     * 
+     * @return int If > 0 the pid of the new process; if 0 the process is
+     *         being emulated by a thread
+     * @throws RuntimeException on fatal start failure
+     * 
+     * {@hide}
+     */
+    public static final int start(final String processClass,
+                                  final String niceName,
+                                  int uid, int gid, int[] gids,
+                                  int debugFlags,
+                                  String[] zygoteArgs)
+    {
+        if (supportsProcesses()) {
+            try {
+                return startViaZygote(processClass, niceName, uid, gid, gids,
+                        debugFlags, zygoteArgs);
+            } catch (ZygoteStartFailedEx ex) {
+                Log.e(LOG_TAG,
+                        "Starting VM process through Zygote failed");
+                throw new RuntimeException(
+                        "Starting VM process through Zygote failed", ex);
+            }
+        } else {
+            // Running in single-process mode
+            
+            Runnable runnable = new Runnable() {
+                        public void run() {
+                            Process.invokeStaticMain(processClass);
+                        }
+            };
+            
+            // Thread constructors must not be called with null names (see spec). 
+            if (niceName != null) {
+                new Thread(runnable, niceName).start();
+            } else {
+                new Thread(runnable).start();
+            }
+            
+            return 0;
+        }
+    }
+    
+    /**
+     * Start a new process.  Don't supply a custom nice name.
+     * {@hide}
+     */
+    public static final int start(String processClass, int uid, int gid,
+            int[] gids, int debugFlags, String[] zygoteArgs) {
+        return start(processClass, "", uid, gid, gids, 
+                debugFlags, zygoteArgs);
+    }
+
+    private static void invokeStaticMain(String className) {
+        Class cl;
+        Object args[] = new Object[1];
+
+        args[0] = new String[0];     //this is argv
+   
+        try {
+            cl = Class.forName(className);
+            cl.getMethod("main", new Class[] { String[].class })
+                    .invoke(null, args);            
+        } catch (Exception ex) {
+            // can be: ClassNotFoundException,
+            // NoSuchMethodException, SecurityException,
+            // IllegalAccessException, IllegalArgumentException
+            // InvocationTargetException
+            // or uncaught exception from main()
+
+            Log.e(LOG_TAG, "Exception invoking static main on " 
+                    + className, ex);
+
+            throw new RuntimeException(ex);
+        }
+
+    }
+
+    /** retry interval for opening a zygote socket */
+    static final int ZYGOTE_RETRY_MILLIS = 500;
+
+    /**
+     * Tries to open socket to Zygote process if not already open. If
+     * already open, does nothing.  May block and retry.
+     */
+    private static void openZygoteSocketIfNeeded() 
+            throws ZygoteStartFailedEx {
+
+        int retryCount;
+
+        if (sPreviousZygoteOpenFailed) {
+            /*
+             * If we've failed before, expect that we'll fail again and
+             * don't pause for retries.
+             */
+            retryCount = 0;
+        } else {
+            retryCount = 10;            
+        }
+
+        /*
+         * See bug #811181: Sometimes runtime can make it up before zygote.
+         * Really, we'd like to do something better to avoid this condition,
+         * but for now just wait a bit...
+         */
+        for (int retry = 0
+                ; (sZygoteSocket == null) && (retry < (retryCount + 1))
+                ; retry++ ) {
+
+            if (retry > 0) {
+                try {
+                    Log.i("Zygote", "Zygote not up yet, sleeping...");
+                    Thread.sleep(ZYGOTE_RETRY_MILLIS);
+                } catch (InterruptedException ex) {
+                    // should never happen
+                }
+            }
+
+            try {
+                sZygoteSocket = new LocalSocket();
+
+                sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, 
+                        LocalSocketAddress.Namespace.RESERVED));
+
+                sZygoteInputStream
+                        = new DataInputStream(sZygoteSocket.getInputStream());
+
+                sZygoteWriter =
+                    new BufferedWriter(
+                            new OutputStreamWriter(
+                                    sZygoteSocket.getOutputStream()),
+                            256);
+
+                Log.i("Zygote", "Process: zygote socket opened");
+
+                sPreviousZygoteOpenFailed = false;
+                break;
+            } catch (IOException ex) {
+                if (sZygoteSocket != null) {
+                    try {
+                        sZygoteSocket.close();
+                    } catch (IOException ex2) {
+                        Log.e(LOG_TAG,"I/O exception on close after exception",
+                                ex2);
+                    }
+                }
+
+                sZygoteSocket = null;
+            }
+        }
+
+        if (sZygoteSocket == null) {
+            sPreviousZygoteOpenFailed = true;
+            throw new ZygoteStartFailedEx("connect failed");                 
+        }
+    }
+
+    /**
+     * Sends an argument list to the zygote process, which starts a new child
+     * and returns the child's pid. Please note: the present implementation
+     * replaces newlines in the argument list with spaces.
+     * @param args argument list
+     * @return PID of new child process
+     * @throws ZygoteStartFailedEx if process start failed for any reason
+     */
+    private static int zygoteSendArgsAndGetPid(ArrayList<String> args)
+            throws ZygoteStartFailedEx {
+
+        int pid;
+
+        openZygoteSocketIfNeeded();
+
+        try {
+            /**
+             * See com.android.internal.os.ZygoteInit.readArgumentList()
+             * Presently the wire format to the zygote process is:
+             * a) a count of arguments (argc, in essence)
+             * b) a number of newline-separated argument strings equal to count
+             *
+             * After the zygote process reads these it will write the pid of
+             * the child or -1 on failure.
+             */
+
+            sZygoteWriter.write(Integer.toString(args.size()));
+            sZygoteWriter.newLine();
+
+            int sz = args.size();
+            for (int i = 0; i < sz; i++) {
+                String arg = args.get(i);
+                if (arg.indexOf('\n') >= 0) {
+                    throw new ZygoteStartFailedEx(
+                            "embedded newlines not allowed");
+                }
+                sZygoteWriter.write(arg);
+                sZygoteWriter.newLine();
+            }
+
+            sZygoteWriter.flush();
+
+            // Should there be a timeout on this?
+            pid = sZygoteInputStream.readInt();
+
+            if (pid < 0) {
+                throw new ZygoteStartFailedEx("fork() failed");
+            }
+        } catch (IOException ex) {
+            try {
+                if (sZygoteSocket != null) {
+                    sZygoteSocket.close();
+                }
+            } catch (IOException ex2) {
+                // we're going to fail anyway
+                Log.e(LOG_TAG,"I/O exception on routine close", ex2);
+            }
+
+            sZygoteSocket = null;
+
+            throw new ZygoteStartFailedEx(ex);
+        }
+
+        return pid;
+    }
+
+    /**
+     * Starts a new process via the zygote mechanism.
+     *
+     * @param processClass Class name whose static main() to run
+     * @param niceName 'nice' process name to appear in ps
+     * @param uid a POSIX uid that the new process should setuid() to
+     * @param gid a POSIX gid that the new process shuold setgid() to
+     * @param gids null-ok; a list of supplementary group IDs that the
+     * new process should setgroup() to.
+     * @param enableDebugger True if debugging should be enabled for this process.
+     * @param extraArgs Additional arguments to supply to the zygote process.
+     * @return PID
+     * @throws ZygoteStartFailedEx if process start failed for any reason
+     */
+    private static int startViaZygote(final String processClass,
+                                  final String niceName,
+                                  final int uid, final int gid,
+                                  final int[] gids,
+                                  int debugFlags,
+                                  String[] extraArgs)
+                                  throws ZygoteStartFailedEx {
+        int pid;
+
+        synchronized(Process.class) {
+            ArrayList<String> argsForZygote = new ArrayList<String>();
+
+            // --runtime-init, --setuid=, --setgid=,
+            // and --setgroups= must go first
+            argsForZygote.add("--runtime-init");
+            argsForZygote.add("--setuid=" + uid);
+            argsForZygote.add("--setgid=" + gid);
+            if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
+                argsForZygote.add("--enable-debugger");
+            }
+            if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
+                argsForZygote.add("--enable-checkjni");
+            }
+            if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
+                argsForZygote.add("--enable-assert");
+            }
+
+            //TODO optionally enable debuger
+            //argsForZygote.add("--enable-debugger");
+
+            // --setgroups is a comma-separated list
+            if (gids != null && gids.length > 0) {
+                StringBuilder sb = new StringBuilder();
+                sb.append("--setgroups=");
+
+                int sz = gids.length;
+                for (int i = 0; i < sz; i++) {
+                    if (i != 0) {
+                        sb.append(',');
+                    }
+                    sb.append(gids[i]);
+                }
+
+                argsForZygote.add(sb.toString());
+            }
+
+            if (niceName != null) {
+                argsForZygote.add("--nice-name=" + niceName);
+            }
+
+            argsForZygote.add(processClass);
+
+            if (extraArgs != null) {
+                for (String arg : extraArgs) {
+                    argsForZygote.add(arg);
+                }
+            }
+            
+            pid = zygoteSendArgsAndGetPid(argsForZygote);
+        }
+
+        if (pid <= 0) {
+            throw new ZygoteStartFailedEx("zygote start failed:" + pid);
+        }
+
+        return pid;
+    }
+    
+    /**
+     * Returns elapsed milliseconds of the time this process has run.
+     * @return  Returns the number of milliseconds this process has return.
+     */
+    public static final native long getElapsedCpuTime();
+    
+    /**
+     * Returns the identifier of this process, which can be used with
+     * {@link #killProcess} and {@link #sendSignal}.
+     */
+    public static final native int myPid();
+
+    /**
+     * Returns the identifier of the calling thread, which be used with
+     * {@link #setThreadPriority(int, int)}.
+     */
+    public static final native int myTid();
+
+    /**
+     * Returns the identifier of this process's user.
+     */
+    public static final native int myUid();
+
+    /**
+     * Returns the UID assigned to a particular user name, or -1 if there is
+     * none.  If the given string consists of only numbers, it is converted
+     * directly to a uid.
+     */
+    public static final native int getUidForName(String name);
+    
+    /**
+     * Returns the GID assigned to a particular user name, or -1 if there is
+     * none.  If the given string consists of only numbers, it is converted
+     * directly to a gid.
+     */
+    public static final native int getGidForName(String name);
+    
+    /**
+     * Set the priority of a thread, based on Linux priorities.
+     * 
+     * @param tid The identifier of the thread/process to change.
+     * @param priority A Linux priority level, from -20 for highest scheduling
+     * priority to 19 for lowest scheduling priority.
+     * 
+     * @throws IllegalArgumentException Throws IllegalArgumentException if
+     * <var>tid</var> does not exist.
+     * @throws SecurityException Throws SecurityException if your process does
+     * not have permission to modify the given thread, or to use the given
+     * priority.
+     */
+    public static final native void setThreadPriority(int tid, int priority)
+            throws IllegalArgumentException, SecurityException;
+    
+    /**
+     * Set the priority of the calling thread, based on Linux priorities.  See
+     * {@link #setThreadPriority(int, int)} for more information.
+     * 
+     * @param priority A Linux priority level, from -20 for highest scheduling
+     * priority to 19 for lowest scheduling priority.
+     * 
+     * @throws IllegalArgumentException Throws IllegalArgumentException if
+     * <var>tid</var> does not exist.
+     * @throws SecurityException Throws SecurityException if your process does
+     * not have permission to modify the given thread, or to use the given
+     * priority.
+     * 
+     * @see #setThreadPriority(int, int)
+     */
+    public static final native void setThreadPriority(int priority)
+            throws IllegalArgumentException, SecurityException;
+    
+    /**
+     * Return the current priority of a thread, based on Linux priorities.
+     * 
+     * @param tid The identifier of the thread/process to change.
+     * 
+     * @return Returns the current priority, as a Linux priority level,
+     * from -20 for highest scheduling priority to 19 for lowest scheduling
+     * priority.
+     * 
+     * @throws IllegalArgumentException Throws IllegalArgumentException if
+     * <var>tid</var> does not exist.
+     */
+    public static final native int getThreadPriority(int tid)
+            throws IllegalArgumentException;
+    
+    /**
+     * Determine whether the current environment supports multiple processes.
+     * 
+     * @return Returns true if the system can run in multiple processes, else
+     * false if everything is running in a single process.
+     */
+    public static final native boolean supportsProcesses();
+
+    /**
+     * Set the out-of-memory badness adjustment for a process.
+     * 
+     * @param pid The process identifier to set.
+     * @param amt Adjustment value -- linux allows -16 to +15.
+     * 
+     * @return Returns true if the underlying system supports this
+     *         feature, else false.
+     *         
+     * {@hide}
+     */
+    public static final native boolean setOomAdj(int pid, int amt);
+
+    /**
+     * Change this process's argv[0] parameter.  This can be useful to show
+     * more descriptive information in things like the 'ps' command.
+     * 
+     * @param text The new name of this process.
+     * 
+     * {@hide}
+     */
+    public static final native void setArgV0(String text);
+
+    /**
+     * Kill the process with the given PID.
+     * Note that, though this API allows us to request to
+     * kill any process based on its PID, the kernel will
+     * still impose standard restrictions on which PIDs you
+     * are actually able to kill.  Typically this means only
+     * the process running the caller's packages/application
+     * and any additional processes created by that app; packages
+     * sharing a common UID will also be able to kill each
+     * other's processes.
+     */
+    public static final void killProcess(int pid) {
+        sendSignal(pid, SIGNAL_KILL);
+    }
+
+    /** @hide */
+    public static final native int setUid(int uid);
+
+    /** @hide */
+    public static final native int setGid(int uid);
+
+    /**
+     * Send a signal to the given process.
+     * 
+     * @param pid The pid of the target process.
+     * @param signal The signal to send.
+     */
+    public static final native void sendSignal(int pid, int signal);
+    
+    /** @hide */
+    public static final native int getFreeMemory();
+    
+    /** @hide */
+    public static final native void readProcLines(String path,
+            String[] reqFields, long[] outSizes);
+    
+    /** @hide */
+    public static final native int[] getPids(String path, int[] lastArray);
+    
+    /** @hide */
+    public static final int PROC_TERM_MASK = 0xff;
+    /** @hide */
+    public static final int PROC_ZERO_TERM = 0;
+    /** @hide */
+    public static final int PROC_SPACE_TERM = (int)' ';
+    /** @hide */
+    public static final int PROC_COMBINE = 0x100;
+    /** @hide */
+    public static final int PROC_PARENS = 0x200;
+    /** @hide */
+    public static final int PROC_OUT_STRING = 0x1000;
+    /** @hide */
+    public static final int PROC_OUT_LONG = 0x2000;
+    /** @hide */
+    public static final int PROC_OUT_FLOAT = 0x4000;
+    
+    /** @hide */
+    public static final native boolean readProcFile(String file, int[] format,
+            String[] outStrings, long[] outLongs, float[] outFloats);
+
+    /**
+     * Gets the total Pss value for a given process, in bytes.
+     * 
+     * @param pid the process to the Pss for
+     * @return the total Pss value for the given process in bytes,
+     *  or -1 if the value cannot be determined 
+     * @hide
+     */
+    public static final native long getPss(int pid);
+}
diff --git a/core/java/android/os/Registrant.java b/core/java/android/os/Registrant.java
new file mode 100644
index 0000000..c1780b9
--- /dev/null
+++ b/core/java/android/os/Registrant.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2006 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.os.Handler;
+import android.os.Message;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+
+/** @hide */
+public class Registrant
+{
+    public
+    Registrant(Handler h, int what, Object obj)
+    {
+        refH = new WeakReference(h);
+        this.what = what;
+        userObj = obj;
+    }
+
+    public void
+    clear()
+    {
+        refH = null;
+        userObj = null;
+    }
+
+    public void
+    notifyRegistrant()
+    {
+        internalNotifyRegistrant (null, null);
+    }
+    
+    public void
+    notifyResult(Object result)
+    {
+        internalNotifyRegistrant (result, null);
+    }
+
+    public void
+    notifyException(Throwable exception)
+    {
+        internalNotifyRegistrant (null, exception);
+    }
+
+    /**
+     * This makes a copy of @param ar
+     */
+    public void
+    notifyRegistrant(AsyncResult ar)
+    {
+        internalNotifyRegistrant (ar.result, ar.exception);
+    }
+
+    /*package*/ void
+    internalNotifyRegistrant (Object result, Throwable exception)
+    {
+        Handler h = getHandler();
+
+        if (h == null) {
+            clear();
+        } else {
+            Message msg = Message.obtain();
+
+            msg.what = what;
+            
+            msg.obj = new AsyncResult(userObj, result, exception);
+            
+            h.sendMessage(msg);
+        }
+    }
+
+    /**
+     * NOTE: May return null if weak reference has been collected
+     */
+
+    public Message
+    messageForRegistrant()
+    {
+        Handler h = getHandler();
+
+        if (h == null) {
+            clear();
+
+            return null;
+        } else {
+            Message msg = h.obtainMessage();
+
+            msg.what = what;
+            msg.obj = userObj;
+
+            return msg;
+        }
+    }
+
+    public Handler
+    getHandler()
+    {
+        if (refH == null)
+            return null;
+
+        return (Handler) refH.get();
+    }
+
+    WeakReference   refH;
+    int             what;
+    Object          userObj;
+}
+
diff --git a/core/java/android/os/RegistrantList.java b/core/java/android/os/RegistrantList.java
new file mode 100644
index 0000000..56b9e2b
--- /dev/null
+++ b/core/java/android/os/RegistrantList.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2006 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.os.Handler;         
+import android.os.Message;         
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/** @hide */
+public class RegistrantList
+{
+    ArrayList   registrants = new ArrayList();      // of Registrant
+
+    public synchronized void
+    add(Handler h, int what, Object obj)
+    {
+        add(new Registrant(h, what, obj));
+    }
+
+    public synchronized void
+    addUnique(Handler h, int what, Object obj)
+    {
+        // if the handler is already in the registrant list, remove it
+        remove(h);
+        add(new Registrant(h, what, obj));        
+    }
+    
+    public synchronized void
+    add(Registrant r)
+    {
+        removeCleared();
+        registrants.add(r);
+    }
+
+    public synchronized void
+    removeCleared()
+    {
+        for (int i = registrants.size() - 1; i >= 0 ; i--) {
+            Registrant  r = (Registrant) registrants.get(i);
+            
+            if (r.refH == null) {
+                registrants.remove(i);
+            }
+        }
+    }
+
+    public synchronized int
+    size()
+    {
+        return registrants.size();
+    }
+
+    public synchronized Object
+    get(int index)
+    {
+        return registrants.get(index);
+    }
+
+    private synchronized void
+    internalNotifyRegistrants (Object result, Throwable exception)
+    {
+       for (int i = 0, s = registrants.size(); i < s ; i++) {
+            Registrant  r = (Registrant) registrants.get(i);
+            r.internalNotifyRegistrant(result, exception);
+       }
+    }
+    
+    public /*synchronized*/ void
+    notifyRegistrants()
+    {
+        internalNotifyRegistrants(null, null);
+    }
+
+    public /*synchronized*/ void
+    notifyException(Throwable exception)
+    {
+        internalNotifyRegistrants (null, exception);
+    }
+
+    public /*synchronized*/ void
+    notifyResult(Object result)
+    {
+        internalNotifyRegistrants (result, null);
+    }
+
+    
+    public /*synchronized*/ void
+    notifyRegistrants(AsyncResult ar)
+    {
+        internalNotifyRegistrants(ar.result, ar.exception);
+    }
+    
+    public synchronized void
+    remove(Handler h)
+    {
+        for (int i = 0, s = registrants.size() ; i < s ; i++) {
+            Registrant  r = (Registrant) registrants.get(i);
+            Handler     rh;
+
+            rh = r.getHandler();
+
+            /* Clean up both the requested registrant and
+             * any now-collected registrants
+             */
+            if (rh == null || rh == h) {
+                r.clear();
+            }
+        }
+
+        removeCleared();
+    }
+}
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
new file mode 100644
index 0000000..04e7ef0
--- /dev/null
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2008 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 java.util.HashMap;
+
+/**
+ * Takes care of the grunt work of maintaining a list of remote interfaces,
+ * typically for the use of performing callbacks from a
+ * {@link android.app.Service} to its clients.  In particular, this:
+ * 
+ * <ul>
+ * <li> Keeps track of a set of registered {@link IInterface} callbacks,
+ * taking care to identify them through their underlying unique {@link IBinder}
+ * (by calling {@link IInterface#asBinder IInterface.asBinder()}.
+ * <li> Attaches a {@link IBinder.DeathRecipient IBinder.DeathRecipient} to
+ * each registered interface, so that it can be cleaned out of the list if its
+ * process goes away.
+ * <li> Performs locking of the underlying list of interfaces to deal with
+ * multithreaded incoming calls, and a thread-safe way to iterate over a
+ * snapshot of the list without holding its lock.
+ * </ul>
+ * 
+ * <p>To use this class, simply create a single instance along with your
+ * service, and call its {@link #register} and {@link #unregister} methods
+ * as client register and unregister with your service.  To call back on to
+ * the registered clients, use {@link #beginBroadcast},
+ * {@link #getBroadcastItem}, and {@link #finishBroadcast}.
+ * 
+ * <p>If a registered callback's process goes away, this class will take
+ * care of automatically removing it from the list.  If you want to do
+ * additional work in this situation, you can create a subclass that
+ * implements the {@link #onCallbackDied} method.
+ */
+public class RemoteCallbackList<E extends IInterface> {
+    /*package*/ HashMap<IBinder, Callback> mCallbacks
+            = new HashMap<IBinder, Callback>();
+    private IInterface[] mActiveBroadcast;
+    private boolean mKilled = false;
+    
+    private final class Callback implements IBinder.DeathRecipient {
+        final E mCallback;
+        
+        Callback(E callback) {
+            mCallback = callback;
+        }
+        
+        public void binderDied() {
+            synchronized (mCallbacks) {
+                mCallbacks.remove(mCallback.asBinder());
+            }
+            onCallbackDied(mCallback);
+        }
+    }
+    
+    /**
+     * Add a new callback to the list.  This callback will remain in the list
+     * until a corresponding call to {@link #unregister} or its hosting process
+     * goes away.  If the callback was already registered (determined by
+     * checking to see if the {@link IInterface#asBinder callback.asBinder()}
+     * object is already in the list), then it will be left as-is.
+     * Registrations are not counted; a single call to {@link #unregister}
+     * will remove a callback after any number calls to register it.
+     * 
+     * @param callback The callback interface to be added to the list.  Must
+     * not be null -- passing null here will cause a NullPointerException.
+     * Most services will want to check for null before calling this with
+     * an object given from a client, so that clients can't crash the
+     * service with bad data.
+     * 
+     * @return Returns true if the callback was successfully added to the list.
+     * Returns false if it was not added, either because {@link #kill} had
+     * previously been called or the callback's process has gone away.
+     * 
+     * @see #unregister
+     * @see #kill
+     * @see #onCallbackDied
+     */
+    public boolean register(E callback) {
+        synchronized (mCallbacks) {
+            if (mKilled) {
+                return false;
+            }
+            IBinder binder = callback.asBinder();
+            try {
+                Callback cb = new Callback(callback);
+                binder.linkToDeath(cb, 0);
+                mCallbacks.put(binder, cb);
+                return true;
+            } catch (RemoteException e) {
+                return false;
+            }
+        }
+    }
+    
+    /**
+     * Remove from the list a callback that was previously added with
+     * {@link #register}.  This uses the
+     * {@link IInterface#asBinder callback.asBinder()} object to correctly
+     * find the previous registration.
+     * Registrations are not counted; a single unregister call will remove
+     * a callback after any number calls to {@link #register} for it.
+     * 
+     * @param callback The callback to be removed from the list.  Passing
+     * null here will cause a NullPointerException, so you will generally want
+     * to check for null before calling.
+     * 
+     * @return Returns true if the callback was found and unregistered.  Returns
+     * false if the given callback was not found on the list.
+     * 
+     * @see #register
+     */
+    public boolean unregister(E callback) {
+        synchronized (mCallbacks) {
+            Callback cb = mCallbacks.remove(callback.asBinder());
+            if (cb != null) {
+                cb.mCallback.asBinder().unlinkToDeath(cb, 0);
+                return true;
+            }
+            return false;
+        }
+    }
+    
+    /**
+     * Disable this callback list.  All registered callbacks are unregistered,
+     * and the list is disabled so that future calls to {@link #register} will
+     * fail.  This should be used when a Service is stopping, to prevent clients
+     * from registering callbacks after it is stopped.
+     * 
+     * @see #register
+     */
+    public void kill() {
+        synchronized (mCallbacks) {
+            for (Callback cb : mCallbacks.values()) {
+                cb.mCallback.asBinder().unlinkToDeath(cb, 0);
+            }
+            mCallbacks.clear();
+            mKilled = true;
+        }
+    }
+    
+    /**
+     * Called when the process hosting a callback in the list has gone away.
+     * The default implementation does nothing.
+     * 
+     * @param callback The callback whose process has died.  Note that, since
+     * its process has died, you can not make any calls on to this interface.
+     * You can, however, retrieve its IBinder and compare it with another
+     * IBinder to see if it is the same object.
+     * 
+     * @see #register
+     */
+    public void onCallbackDied(E callback) {
+    }
+    
+    /**
+     * Prepare to start making calls to the currently registered callbacks.
+     * This creates a copy of the callback list, which you can retrieve items
+     * from using {@link #getBroadcastItem}.  Note that only one broadcast can
+     * be active at a time, so you must be sure to always call this from the
+     * same thread (usually by scheduling with {@link Handler} or
+     * do your own synchronization.  You must call {@link #finishBroadcast}
+     * when done.
+     * 
+     * <p>A typical loop delivering a broadcast looks like this:
+     * 
+     * <pre>
+     * final int N = callbacks.beginBroadcast();
+     * for (int i=0; i<N; i++) {
+     *     try {
+     *         callbacks.getBroadcastItem(i).somethingHappened();
+     *     } catch (RemoteException e) {
+     *         // The RemoteCallbackList will take care of removing
+     *         // the dead object for us.
+     *     }
+     * }
+     * callbacks.finishBroadcast();</pre>
+     * 
+     * @return Returns the number of callbacks in the broadcast, to be used
+     * with {@link #getBroadcastItem} to determine the range of indices you
+     * can supply.
+     * 
+     * @see #getBroadcastItem
+     * @see #finishBroadcast
+     */
+    public int beginBroadcast() {
+        synchronized (mCallbacks) {
+            final int N = mCallbacks.size();
+            if (N <= 0) {
+                return 0;
+            }
+            IInterface[] active = mActiveBroadcast;
+            if (active == null || active.length < N) {
+                mActiveBroadcast = active = new IInterface[N];
+            }
+            int i=0;
+            for (Callback cb : mCallbacks.values()) {
+                active[i++] = cb.mCallback;
+            }
+            return N;
+        }
+    }
+    
+    /**
+     * Retrieve an item in the active broadcast that was previously started
+     * with {@link #beginBroadcast}.  This can <em>only</em> be called after
+     * the broadcast is started, and its data is no longer valid after
+     * calling {@link #finishBroadcast}.
+     * 
+     * <p>Note that it is possible for the process of one of the returned
+     * callbacks to go away before you call it, so you will need to catch
+     * {@link RemoteException} when calling on to the returned object.
+     * The callback list itself, however, will take care of unregistering
+     * these objects once it detects that it is no longer valid, so you can
+     * handle such an exception by simply ignoring it.
+     * 
+     * @param index Which of the registered callbacks you would like to
+     * retrieve.  Ranges from 0 to 1-{@link #beginBroadcast}.
+     * 
+     * @return Returns the callback interface that you can call.  This will
+     * always be non-null.
+     * 
+     * @see #beginBroadcast
+     */
+    public E getBroadcastItem(int index) {
+        return (E)mActiveBroadcast[index];
+    }
+    
+    /**
+     * Clean up the state of a broadcast previously initiated by calling
+     * {@link #beginBroadcast}.  This must always be called when you are done
+     * with a broadcast.
+     * 
+     * @see #beginBroadcast
+     */
+    public void finishBroadcast() {
+        IInterface[] active = mActiveBroadcast;
+        if (active != null) {
+            final int N = active.length;
+            for (int i=0; i<N; i++) {
+                active[i] = null;
+            }
+        }
+    }
+}
diff --git a/core/java/android/os/RemoteException.java b/core/java/android/os/RemoteException.java
new file mode 100644
index 0000000..9d76156
--- /dev/null
+++ b/core/java/android/os/RemoteException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2006 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.AndroidException;
+
+/**
+ * Parent exception for all Binder remote-invocation errors
+ */
+public class RemoteException extends AndroidException {
+    public RemoteException() {
+        super();
+    }
+}
diff --git a/core/java/android/os/RemoteMailException.java b/core/java/android/os/RemoteMailException.java
new file mode 100644
index 0000000..1ac96d1
--- /dev/null
+++ b/core/java/android/os/RemoteMailException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 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;
+
+/** @hide */
+public class RemoteMailException extends Exception
+{
+    public RemoteMailException()
+    {
+    }
+
+    public RemoteMailException(String s)
+    {
+        super(s);
+    }
+}
+
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
new file mode 100644
index 0000000..b721665
--- /dev/null
+++ b/core/java/android/os/ServiceManager.java
@@ -0,0 +1,122 @@
+/*
+ * 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 com.android.internal.os.BinderInternal;
+
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/** @hide */
+public final class ServiceManager {
+    private static final String TAG = "ServiceManager";
+
+    private static IServiceManager sServiceManager;
+    private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
+
+    private static IServiceManager getIServiceManager() {
+        if (sServiceManager != null) {
+            return sServiceManager;
+        }
+
+        // Find the service manager
+        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
+        return sServiceManager;
+    }
+
+    /**
+     * Returns a reference to a service with the given name.
+     * 
+     * @param name the name of the service to get
+     * @return a reference to the service, or <code>null</code> if the service doesn't exist
+     */
+    public static IBinder getService(String name) {
+        try {
+            IBinder service = sCache.get(name);
+            if (service != null) {
+                return service;
+            } else {
+                return getIServiceManager().getService(name);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "error in getService", e);
+        }
+        return null;
+    }
+
+    /**
+     * Place a new @a service called @a name into the service
+     * manager.
+     * 
+     * @param name the name of the new service
+     * @param service the service object
+     */
+    public static void addService(String name, IBinder service) {
+        try {
+            getIServiceManager().addService(name, service);
+        } catch (RemoteException e) {
+            Log.e(TAG, "error in addService", e);
+        }
+    }
+    
+    /**
+     * Retrieve an existing service called @a name from the
+     * service manager.  Non-blocking.
+     */
+    public static IBinder checkService(String name) {
+        try {
+            IBinder service = sCache.get(name);
+            if (service != null) {
+                return service;
+            } else {
+                return getIServiceManager().checkService(name);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "error in checkService", e);
+            return null;
+        }
+    }
+
+    /**
+     * Return a list of all currently running services.
+     */
+    public static String[] listServices() throws RemoteException {
+        try {
+            return getIServiceManager().listServices();
+        } catch (RemoteException e) {
+            Log.e(TAG, "error in listServices", e);
+            return null;
+        }
+    }
+
+    /**
+     * This is only intended to be called when the process is first being brought
+     * up and bound by the activity manager. There is only one thread in the process
+     * at that time, so no locking is done.
+     * 
+     * @param cache the cache of service references
+     * @hide
+     */
+    public static void initServiceCache(Map<String, IBinder> cache) {
+        if (sCache.size() != 0 && Process.supportsProcesses()) {
+            throw new IllegalStateException("setServiceCache may only be called once");
+        }
+        sCache.putAll(cache);
+    }
+}
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
new file mode 100644
index 0000000..2aab0e6
--- /dev/null
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2006 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;
+
+
+/**
+ * Native implementation of the service manager.  Most clients will only
+ * care about getDefault() and possibly asInterface().
+ * @hide
+ */
+public abstract class ServiceManagerNative extends Binder implements IServiceManager
+{
+    /**
+     * Cast a Binder object into a service manager interface, generating
+     * a proxy if needed.
+     */
+    static public IServiceManager asInterface(IBinder obj)
+    {
+        if (obj == null) {
+            return null;
+        }
+        IServiceManager in =
+            (IServiceManager)obj.queryLocalInterface(descriptor);
+        if (in != null) {
+            return in;
+        }
+        
+        return new ServiceManagerProxy(obj);
+    }
+    
+    public ServiceManagerNative()
+    {
+        attachInterface(this, descriptor);
+    }
+    
+    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+    {
+        try {
+            switch (code) {
+            case IServiceManager.GET_SERVICE_TRANSACTION: {
+                data.enforceInterface(IServiceManager.descriptor);
+                String name = data.readString();
+                IBinder service = getService(name);
+                reply.writeStrongBinder(service);
+                return true;
+            }
+    
+            case IServiceManager.CHECK_SERVICE_TRANSACTION: {
+                data.enforceInterface(IServiceManager.descriptor);
+                String name = data.readString();
+                IBinder service = checkService(name);
+                reply.writeStrongBinder(service);
+                return true;
+            }
+    
+            case IServiceManager.ADD_SERVICE_TRANSACTION: {
+                data.enforceInterface(IServiceManager.descriptor);
+                String name = data.readString();
+                IBinder service = data.readStrongBinder();
+                addService(name, service);
+                return true;
+            }
+    
+            case IServiceManager.LIST_SERVICES_TRANSACTION: {
+                data.enforceInterface(IServiceManager.descriptor);
+                String[] list = listServices();
+                reply.writeStringArray(list);
+                return true;
+            }
+            
+            case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
+                data.enforceInterface(IServiceManager.descriptor);
+                IPermissionController controller
+                        = IPermissionController.Stub.asInterface(
+                                data.readStrongBinder());
+                setPermissionController(controller);
+                return true;
+            }
+            }
+        } catch (RemoteException e) {
+        }
+        
+        return false;
+    }
+
+    public IBinder asBinder()
+    {
+        return this;
+    }
+}
+
+class ServiceManagerProxy implements IServiceManager {
+    public ServiceManagerProxy(IBinder remote) {
+        mRemote = remote;
+    }
+    
+    public IBinder asBinder() {
+        return mRemote;
+    }
+    
+    public IBinder getService(String name) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IServiceManager.descriptor);
+        data.writeString(name);
+        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
+        IBinder binder = reply.readStrongBinder();
+        reply.recycle();
+        data.recycle();
+        return binder;
+    }
+
+    public IBinder checkService(String name) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IServiceManager.descriptor);
+        data.writeString(name);
+        mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
+        IBinder binder = reply.readStrongBinder();
+        reply.recycle();
+        data.recycle();
+        return binder;
+    }
+
+    public void addService(String name, IBinder service)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IServiceManager.descriptor);
+        data.writeString(name);
+        data.writeStrongBinder(service);
+        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
+        reply.recycle();
+        data.recycle();
+    }
+    
+    public String[] listServices() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IServiceManager.descriptor);
+        mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
+        String[] list = reply.readStringArray();
+        reply.recycle();
+        data.recycle();
+        return list;
+    }
+
+    public void setPermissionController(IPermissionController controller)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IServiceManager.descriptor);
+        data.writeStrongBinder(controller.asBinder());
+        mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
+        reply.recycle();
+        data.recycle();
+    }
+
+    private IBinder mRemote;
+}
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
new file mode 100644
index 0000000..912bfdf
--- /dev/null
+++ b/core/java/android/os/StatFs.java
@@ -0,0 +1,74 @@
+/*
+ * 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;
+
+/**
+ * Retrieve overall information about the space on a filesystem.  This is a
+ * Wrapper for Unix statfs().
+ */
+public class StatFs {
+    /**
+     * Construct a new StatFs for looking at the stats of the
+     * filesystem at <var>path</var>.  Upon construction, the stat of
+     * the file system will be performed, and the values retrieved available
+     * from the methods on this class.
+     * 
+     * @param path A path in the desired file system to state.
+     */
+    public StatFs(String path) { native_setup(path); }
+    
+    /**
+     * Perform a restat of the file system referenced by this object.  This
+     * is the same as re-constructing the object with the same file system
+     * path, and the new stat values are available upon return.
+     */
+    public void restat(String path) { native_restat(path); }
+
+    @Override
+    protected void finalize() { native_finalize(); }
+
+    /**
+     * The size, in bytes, of a block on the file system.  This corresponds
+     * to the Unix statfs.f_bsize field.
+     */
+    public native int getBlockSize();
+
+    /**
+     * The total number of blocks on the file system.  This corresponds
+     * to the Unix statfs.f_blocks field.
+     */
+    public native int getBlockCount();
+
+    /**
+     * The total number of blocks that are free on the file system, including
+     * reserved blocks (that are not available to normal applications).  This
+     * corresponds to the Unix statfs.f_bfree field.  Most applications will
+     * want to use {@link #getAvailableBlocks()} instead.
+     */
+    public native int getFreeBlocks();
+
+    /**
+     * The number of blocks that are free on the file system and available to
+     * applications.  This corresponds to the Unix statfs.f_bavail field.
+     */
+    public native int getAvailableBlocks();    
+    
+    private int mNativeContext;
+    private native void native_restat(String path);
+    private native void native_setup(String path);
+    private native void native_finalize();
+}
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
new file mode 100644
index 0000000..2b57b39
--- /dev/null
+++ b/core/java/android/os/SystemClock.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2006 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;
+
+
+/**
+ * Core timekeeping facilities.
+ *
+ * <p> Three different clocks are available, and they should not be confused:
+ *
+ * <ul>
+ *     <li> <p> {@link System#currentTimeMillis System.currentTimeMillis()}
+ *     is the standard "wall" clock (time and date) expressing milliseconds
+ *     since the epoch.  The wall clock can be set by the user or the phone
+ *     network (see {@link #setCurrentTimeMillis}), so the time may jump
+ *     backwards or forwards unpredictably.  This clock should only be used
+ *     when correspondence with real-world dates and times is important, such
+ *     as in a calendar or alarm clock application.  Interval or elapsed
+ *     time measurements should use a different clock.
+ *
+ *     <li> <p> {@link #uptimeMillis} is counted in milliseconds since the
+ *     system was booted.  This clock stops when the system enters deep
+ *     sleep (CPU off, display dark, device waiting for external input),
+ *     but is not affected by clock scaling, idle, or other power saving
+ *     mechanisms.  This is the basis for most interval timing
+ *     such as {@link Thread#sleep(long) Thread.sleep(millls)},
+ *     {@link Object#wait(long) Object.wait(millis)}, and
+ *     {@link System#nanoTime System.nanoTime()}.  This clock is guaranteed
+ *     to be monotonic, and is the recommended basis for the general purpose
+ *     interval timing of user interface events, performance measurements,
+ *     and anything else that does not need to measure elapsed time during
+ *     device sleep.  Most methods that accept a timestamp value expect the
+ *     {@link #uptimeMillis} clock.
+ *
+ *     <li> <p> {@link #elapsedRealtime} is counted in milliseconds since the
+ *     system was booted, including deep sleep.  This clock should be used
+ *     when measuring time intervals that may span periods of system sleep.
+ * </ul>
+ *
+ * There are several mechanisms for controlling the timing of events:
+ *
+ * <ul>
+ *     <li> <p> Standard functions like {@link Thread#sleep(long)
+ *     Thread.sleep(millis)} and {@link Object#wait(long) Object.wait(millis)}
+ *     are always available.  These functions use the {@link #uptimeMillis}
+ *     clock; if the device enters sleep, the remainder of the time will be
+ *     postponed until the device wakes up.  These synchronous functions may
+ *     be interrupted with {@link Thread#interrupt Thread.interrupt()}, and
+ *     you must handle {@link InterruptedException}.
+ *
+ *     <li> <p> {@link #sleep SystemClock.sleep(millis)} is a utility function
+ *     very similar to {@link Thread#sleep(long) Thread.sleep(millis)}, but it
+ *     ignores {@link InterruptedException}.  Use this function for delays if
+ *     you do not use {@link Thread#interrupt Thread.interrupt()}, as it will
+ *     preserve the interrupted state of the thread.
+ *
+ *     <li> <p> The {@link android.os.Handler} class can schedule asynchronous
+ *     callbacks at an absolute or relative time.  Handler objects also use the
+ *     {@link #uptimeMillis} clock, and require an {@link android.os.Looper
+ *     event loop} (normally present in any GUI application).
+ *
+ *     <li> <p> The {@link android.app.AlarmManager} can trigger one-time or
+ *     recurring events which occur even when the device is in deep sleep
+ *     or your application is not running.  Events may be scheduled with your
+ *     choice of {@link java.lang.System#currentTimeMillis} (RTC) or
+ *     {@link #elapsedRealtime} (ELAPSED_REALTIME), and cause an
+ *     {@link android.content.Intent} broadcast when they occur.
+ * </ul>
+ */
+public final class SystemClock {
+    /**
+     * This class is uninstantiable.
+     */
+    private SystemClock() {
+        // This space intentionally left blank.
+    }
+
+    /**
+     * Waits a given number of milliseconds (of uptimeMillis) before returning.
+     * Similar to {@link java.lang.Thread#sleep(long)}, but does not throw
+     * {@link InterruptedException}; {@link Thread#interrupt()} events are
+     * deferred until the next interruptible operation.  Does not return until
+     * at least the specified number of milliseconds has elapsed.
+     *
+     * @param ms to sleep before returning, in milliseconds of uptime.
+     */
+    public static void sleep(long ms)
+    {
+        long start = uptimeMillis();
+        long duration = ms;
+        boolean interrupted = false;
+        do {
+            try {
+                Thread.sleep(duration);
+            }
+            catch (InterruptedException e) {
+                interrupted = true;
+            }
+            duration = start + ms - uptimeMillis();
+        } while (duration > 0);
+        
+        if (interrupted) {
+            // Important: we don't want to quietly eat an interrupt() event,
+            // so we make sure to re-interrupt the thread so that the next
+            // call to Thread.sleep() or Object.wait() will be interrupted.
+            Thread.currentThread().interrupt();
+        }
+    }
+    
+    /**
+     * Sets the current wall time, in milliseconds.  Requires the calling
+     * process to have appropriate permissions.
+     *
+     * @return if the clock was successfully set to the specified time.
+     */
+    native public static boolean setCurrentTimeMillis(long millis);
+
+    /**
+     * Returns milliseconds since boot, not counting time spent in deep sleep.
+     * <b>Note:</b> This value may get reset occasionally (before it would
+     * otherwise wrap around).
+     *
+     * @return milliseconds of non-sleep uptime since boot.
+     */
+    native public static long uptimeMillis();
+
+    /**
+     * Returns milliseconds since boot, including time spent in sleep.
+     *
+     * @return elapsed milliseconds since boot.
+     */
+    native public static long elapsedRealtime();
+    
+    /**
+     * Returns milliseconds running in the current thread.
+     * 
+     * @return elapsed milliseconds in the thread
+     */
+    public static native long currentThreadTimeMillis();
+}
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
new file mode 100644
index 0000000..c3ae3c2
--- /dev/null
+++ b/core/java/android/os/SystemProperties.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2006 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;
+
+
+/**
+ * Gives access to the system properties store.  The system properties
+ * store contains a list of string key-value pairs.
+ *
+ * {@hide}
+ */
+public class SystemProperties
+{
+    public static final int PROP_NAME_MAX = 31;
+    public static final int PROP_VALUE_MAX = 91;
+
+    private static native String native_get(String key);
+    private static native String native_get(String key, String def);
+    private static native void native_set(String key, String def);
+
+    /**
+     * Get the value for the given key.
+     * @return an empty string if the key isn't found
+     * @throws IllegalArgumentException if the key exceeds 32 characters
+     */
+    public static String get(String key) {
+        if (key.length() > PROP_NAME_MAX) {
+            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
+        }
+        return native_get(key);
+    }
+
+    /**
+     * Get the value for the given key.
+     * @return if the key isn't found, return def if it isn't null, or an empty string otherwise
+     * @throws IllegalArgumentException if the key exceeds 32 characters
+     */
+    public static String get(String key, String def) {
+        if (key.length() > PROP_NAME_MAX) {
+            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
+        }
+        return native_get(key, def);
+    }
+
+    /**
+     * Get the value for the given key, and return as an integer.
+     * @param key the key to lookup
+     * @param def a default value to return
+     * @return the key parsed as an integer, or def if the key isn't found or
+     *         cannot be parsed
+     * @throws IllegalArgumentException if the key exceeds 32 characters
+     */
+    public static int getInt(String key, int def) {
+        try {
+            return Integer.parseInt(get(key));
+        } catch (NumberFormatException e) {
+            return def;
+        }
+    }
+
+    /**
+     * Get the value for the given key, and return as a long.
+     * @param key the key to lookup
+     * @param def a default value to return
+     * @return the key parsed as a long, or def if the key isn't found or
+     *         cannot be parsed
+     * @throws IllegalArgumentException if the key exceeds 32 characters
+     */
+    public static long getLong(String key, long def) {
+        try {
+            return Long.parseLong(get(key));
+        } catch (NumberFormatException e) {
+            return def;
+        }
+    }
+
+    /**
+     * Get the value for the given key, returned as a boolean.
+     * Values 'n', 'no', '0', 'false' or 'off' are considered false.
+     * Values 'y', 'yes', '1', 'true' or 'on' are considered true.
+     * (case insensitive).
+     * If the key does not exist, or has any other value, then the default
+     * result is returned.
+     * @param key the key to lookup
+     * @param def a default value to return
+     * @return the key parsed as a boolean, or def if the key isn't found or is
+     *         not able to be parsed as a boolean.
+     * @throws IllegalArgumentException if the key exceeds 32 characters
+     */
+    public static boolean getBoolean(String key, boolean def) {
+        String value = get(key);
+        // Deal with these quick cases first: not found, 0 and 1
+        if (value.equals("")) {
+            return def;
+        } else if (value.equals("0")) {
+            return false;
+        } else if (value.equals("1")) {
+            return true;
+        // now for slower (and hopefully less common) cases
+        } else if (value.equalsIgnoreCase("n") ||
+                   value.equalsIgnoreCase("no") ||
+                   value.equalsIgnoreCase("false") ||
+                   value.equalsIgnoreCase("off")) {
+            return false;
+        } else if (value.equalsIgnoreCase("y") ||
+                   value.equalsIgnoreCase("yes") ||
+                   value.equalsIgnoreCase("true") ||
+                   value.equalsIgnoreCase("on")) {
+            return true;
+        }
+        return def;
+    }
+
+    /**
+     * Set the value for the given key.
+     * @throws IllegalArgumentException if the key exceeds 32 characters
+     * @throws IllegalArgumentException if the value exceeds 92 characters
+     */
+    public static void set(String key, String val) {
+        if (key.length() > PROP_NAME_MAX) {
+            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
+        }
+        if (val != null && val.length() > PROP_VALUE_MAX) {
+            throw new IllegalArgumentException("val.length > " +
+                PROP_VALUE_MAX);
+        }
+        native_set(key, val);
+    }
+}
diff --git a/core/java/android/os/SystemService.java b/core/java/android/os/SystemService.java
new file mode 100644
index 0000000..447cd1f
--- /dev/null
+++ b/core/java/android/os/SystemService.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 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;
+
+/** @hide */
+public class SystemService
+{
+        /** Request that the init daemon start a named service. */
+    public static void start(String name) {
+        SystemProperties.set("ctl.start", name);
+    }
+    
+        /** Request that the init daemon stop a named service. */
+    public static void stop(String name) {
+        SystemProperties.set("ctl.stop", name);
+    }
+}
diff --git a/core/java/android/os/TokenWatcher.java b/core/java/android/os/TokenWatcher.java
new file mode 100755
index 0000000..ac3cc92
--- /dev/null
+++ b/core/java/android/os/TokenWatcher.java
@@ -0,0 +1,197 @@
+/*
+ * 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 java.util.WeakHashMap;
+import java.util.Set;
+import android.util.Log;
+
+/**
+ * Helper class that helps you use IBinder objects as reference counted
+ * tokens.  IBinders make good tokens because we find out when they are
+ * removed
+ *
+ */
+public abstract class TokenWatcher
+{
+    /**
+     * Construct the TokenWatcher
+     *
+     * @param h A handler to call {@link #acquired} and {@link #released}
+     * on.  If you don't care, just call it like this, although your thread
+     * will have to be a Looper thread.
+     * <code>new TokenWatcher(new Handler())</code>
+     * @param tag A debugging tag for this TokenWatcher
+     */
+    public TokenWatcher(Handler h, String tag)
+    {
+        mHandler = h;
+        mTag = tag != null ? tag : "TokenWatcher";
+    }
+
+    /**
+     * Called when the number of active tokens goes from 0 to 1.
+     */
+    public abstract void acquired();
+
+    /**
+     * Called when the number of active tokens goes from 1 to 0.
+     */
+    public abstract void released();
+
+    /**
+     * Record that this token has been acquired.  When acquire is called, and
+     * the current count is 0, the acquired method is called on the given
+     * handler.
+     * 
+     * @param token An IBinder object.  If this token has already been acquired,
+     *              no action is taken.
+     * @param tag   A string used by the {@link #dump} method for debugging,
+     *              to see who has references.
+     */
+    public void acquire(IBinder token, String tag)
+    {
+        synchronized (mTokens) {
+            // explicitly checked to avoid bogus sendNotification calls because
+            // of the WeakHashMap and the GC
+            int oldSize = mTokens.size();
+
+            Death d = new Death(token, tag);
+            try {
+                token.linkToDeath(d, 0);
+            } catch (RemoteException e) {
+                return;
+            }
+            mTokens.put(token, d);
+
+            if (oldSize == 0 && !mAcquired) {
+                sendNotificationLocked(true);
+                mAcquired = true;
+            }
+        }
+    }
+
+    public void cleanup(IBinder token, boolean unlink)
+    {
+        synchronized (mTokens) {
+            Death d = mTokens.remove(token);
+            if (unlink && d != null) {
+                d.token.unlinkToDeath(d, 0);
+                d.token = null;
+            }
+
+            if (mTokens.size() == 0 && mAcquired) {
+                sendNotificationLocked(false);
+                mAcquired = false;
+            }
+        }
+    }
+
+    public void release(IBinder token)
+    {
+        cleanup(token, true);
+    }
+
+    public boolean isAcquired()
+    {
+        synchronized (mTokens) {
+            return mAcquired;
+        }
+    }
+
+    public void dump()
+    {
+        synchronized (mTokens) {
+            Set<IBinder> keys = mTokens.keySet();
+            Log.i(mTag, "Token count: " + mTokens.size());
+            int i = 0;
+            for (IBinder b: keys) {
+                Log.i(mTag, "[" + i + "] " + mTokens.get(b).tag + " - " + b);
+                i++;
+            }
+        }
+    }
+
+    private Runnable mNotificationTask = new Runnable() {
+        public void run()
+        {
+            int value;
+            synchronized (mTokens) {
+                value = mNotificationQueue;
+                mNotificationQueue = -1;
+            }
+            if (value == 1) {
+                acquired();
+            }
+            else if (value == 0) {
+                released();
+            }
+        }
+    };
+
+    private void sendNotificationLocked(boolean on)
+    {
+        int value = on ? 1 : 0;
+        if (mNotificationQueue == -1) {
+            // empty
+            mNotificationQueue = value;
+            mHandler.post(mNotificationTask);
+        }
+        else if (mNotificationQueue != value) {
+            // it's a pair, so cancel it
+            mNotificationQueue = -1;
+            mHandler.removeCallbacks(mNotificationTask);
+        }
+        // else, same so do nothing -- maybe we should warn?
+    }
+
+    private class Death implements IBinder.DeathRecipient
+    {
+        IBinder token;
+        String tag;
+
+        Death(IBinder token, String tag)
+        {
+            this.token = token;
+            this.tag = tag;
+        }
+
+        public void binderDied()
+        {
+            cleanup(token, false);
+        }
+
+        protected void finalize() throws Throwable
+        {
+            try {
+                if (token != null) {
+                    Log.w(mTag, "cleaning up leaked reference: " + tag);
+                    release(token);
+                }
+            }
+            finally {
+                super.finalize();
+            }
+        }
+    }
+
+    private WeakHashMap<IBinder,Death> mTokens = new WeakHashMap<IBinder,Death>();
+    private Handler mHandler;
+    private String mTag;
+    private int mNotificationQueue = -1;
+    private volatile boolean mAcquired = false;
+}
diff --git a/core/java/android/os/UEventObserver.java b/core/java/android/os/UEventObserver.java
new file mode 100644
index 0000000..b924e84
--- /dev/null
+++ b/core/java/android/os/UEventObserver.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2008 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 java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * UEventObserver is an abstract class that receives UEvent's from the kernel.<p>
+ *
+ * Subclass UEventObserver, implementing onUEvent(UEvent event), then call
+ * startObserving() with a match string. The UEvent thread will then call your
+ * onUEvent() method when a UEvent occurs that contains your match string.<p>
+ *
+ * Call stopObserving() to stop receiving UEvent's.<p>
+ *
+ * There is only one UEvent thread per process, even if that process has
+ * multiple UEventObserver subclass instances. The UEvent thread starts when
+ * the startObserving() is called for the first time in that process. Once
+ * started the UEvent thread will not stop (although it can stop notifying
+ * UEventObserver's via stopObserving()).<p>
+ *
+ * @hide
+*/
+public abstract class UEventObserver {
+    private static final String TAG = UEventObserver.class.getSimpleName();
+
+    /**
+     * Representation of a UEvent.
+     */
+    static public class UEvent {
+        // collection of key=value pairs parsed from the uevent message
+        public HashMap<String,String> mMap = new HashMap<String,String>();
+
+        public UEvent(String message) {
+            int offset = 0;
+            int length = message.length();
+
+            while (offset < length) {
+                int equals = message.indexOf('=', offset);
+                int at = message.indexOf(0, offset);
+                if (at < 0) break;
+
+                if (equals > offset && equals < at) {
+                    // key is before the equals sign, and value is after
+                    mMap.put(message.substring(offset, equals),
+                            message.substring(equals + 1, at));
+                }
+
+                offset = at + 1;
+            }
+        }
+
+        public String get(String key) {
+            return mMap.get(key);
+        }
+
+        public String get(String key, String defaultValue) {
+            String result = mMap.get(key);
+            return (result == null ? defaultValue : result);
+        }
+
+        public String toString() {
+            return mMap.toString();
+        }
+    }
+
+    private static UEventThread sThread;
+    private static boolean sThreadStarted = false;
+
+    private static class UEventThread extends Thread {
+        /** Many to many mapping of string match to observer.
+         *  Multimap would be better, but not available in android, so use
+         *  an ArrayList where even elements are the String match and odd
+         *  elements the corresponding UEventObserver observer */
+        private ArrayList<Object> mObservers = new ArrayList<Object>();
+        
+        UEventThread() {
+            super("UEventObserver");
+        }
+        
+        public void run() {
+            native_setup();
+
+            byte[] buffer = new byte[1024];
+            int len;
+            while (true) {
+                len = next_event(buffer);
+                if (len > 0) {
+                    String bufferStr = new String(buffer, 0, len);  // easier to search a String
+                    synchronized (mObservers) {
+                        for (int i = 0; i < mObservers.size(); i += 2) {
+                            if (bufferStr.indexOf((String)mObservers.get(i)) != -1) {
+                                ((UEventObserver)mObservers.get(i+1))
+                                        .onUEvent(new UEvent(bufferStr));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        public void addObserver(String match, UEventObserver observer) {
+            synchronized(mObservers) {
+                mObservers.add(match);
+                mObservers.add(observer);
+            }
+        }
+        /** Removes every key/value pair where value=observer from mObservers */
+        public void removeObserver(UEventObserver observer) {
+            synchronized(mObservers) {
+                boolean found = true;
+                while (found) {
+                    found = false;
+                    for (int i = 0; i < mObservers.size(); i += 2) {
+                        if (mObservers.get(i+1) == observer) {
+                            mObservers.remove(i+1);
+                            mObservers.remove(i);
+                            found = true;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private static native void native_setup();
+    private static native int next_event(byte[] buffer);
+
+    private static final synchronized void ensureThreadStarted() {
+        if (sThreadStarted == false) {
+            sThread = new UEventThread();
+            sThread.start();
+            sThreadStarted = true;
+        }
+    }
+
+    /**
+     * Begin observation of UEvent's.<p>
+     * This method will cause the UEvent thread to start if this is the first
+     * invocation of startObserving in this process.<p>
+     * Once called, the UEvent thread will call onUEvent() when an incoming
+     * UEvent matches the specified string.<p>
+     * This method can be called multiple times to register multiple matches.
+     * Only one call to stopObserving is required even with multiple registered
+     * matches.
+     * @param match A substring of the UEvent to match. Use "" to match all
+     *              UEvent's
+     */
+    public final synchronized void startObserving(String match) {
+        ensureThreadStarted();
+        sThread.addObserver(match, this);
+    }
+
+    /**
+     * End observation of UEvent's.<p>
+     * This process's UEvent thread will never call onUEvent() on this
+     * UEventObserver after this call. Repeated calls have no effect.
+     */
+    public final synchronized void stopObserving() {
+        sThread.removeObserver(this);
+    }
+
+    /**
+     * Subclasses of UEventObserver should override this method to handle
+     * UEvents.
+     */
+    public abstract void onUEvent(UEvent event);
+
+    protected void finalize() throws Throwable {
+        try {
+            stopObserving();
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
new file mode 100644
index 0000000..0f75289
--- /dev/null
+++ b/core/java/android/os/Vibrator.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2006 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;
+
+/**
+ * Class that operates the vibrator on the device.
+ * <p>
+ * If your process exits, any vibration you started with will stop.
+ */
+public class Vibrator
+{
+    IHardwareService mService;
+
+    /** @hide */
+    public Vibrator()
+    {
+        mService = IHardwareService.Stub.asInterface(
+                ServiceManager.getService("hardware"));
+    }
+
+    /**
+     * Turn the vibrator on.
+     *
+     * @param milliseconds How long to vibrate for.
+     */
+    public void vibrate(long milliseconds)
+    {
+        try {
+            mService.vibrate(milliseconds);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Vibrate with a given pattern.
+     *
+     * <p>
+     * Pass in an array of ints that are the times at which to turn on or off
+     * the vibrator.  The first one is how long to wait before turning it on,
+     * and then after that it alternates.  If you want to repeat, pass the
+     * index into the pattern at which to start the repeat.
+     *
+     * @param pattern an array of longs of times to turn the vibrator on or off.
+     * @param repeat the index into pattern at which to repeat, or -1 if
+     *        you don't want to repeat.
+     */
+    public void vibrate(long[] pattern, int repeat)
+    {
+        // catch this here because the server will do nothing.  pattern may
+        // not be null, let that be checked, because the server will drop it
+        // anyway
+        if (repeat < pattern.length) {
+            try {
+                mService.vibratePattern(pattern, repeat, new Binder());
+            } catch (RemoteException e) {
+            }
+        } else {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Turn the vibrator off.
+     */
+    public void cancel()
+    {
+        try {
+            mService.cancelVibrate();
+        } catch (RemoteException e) {
+        }
+    }
+}
diff --git a/core/java/android/os/package.html b/core/java/android/os/package.html
new file mode 100644
index 0000000..fb0ecda
--- /dev/null
+++ b/core/java/android/os/package.html
@@ -0,0 +1,6 @@
+<HTML>
+<BODY>
+Provides basic operating system services, message passing, and inter-process
+communication on the device.
+</BODY>
+</HTML>
\ No newline at end of file
