diff --git a/Android.mk b/Android.mk
index 2e2fec1..7ece6eb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -108,6 +108,7 @@
 	core/java/android/hardware/ISensorService.aidl \
 	core/java/android/net/IConnectivityManager.aidl \
 	core/java/android/os/ICheckinService.aidl \
+	core/java/android/os/IDropBox.aidl \
 	core/java/android/os/IHardwareService.aidl \
 	core/java/android/os/IMessenger.aidl \
 	core/java/android/os/IMountService.aidl \
@@ -216,6 +217,7 @@
 	frameworks/base/core/java/android/appwidget/AppWidgetProviderInfo.aidl \
 	frameworks/base/core/java/android/net/Uri.aidl \
 	frameworks/base/core/java/android/os/Bundle.aidl \
+	frameworks/base/core/java/android/os/DropBoxEntry.aidl \
 	frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
 	frameworks/base/core/java/android/os/ParcelUuid.aidl \
 	frameworks/base/core/java/android/view/KeyEvent.aidl \
diff --git a/core/java/android/os/DropBoxEntry.aidl b/core/java/android/os/DropBoxEntry.aidl
new file mode 100644
index 0000000..225eee1
--- /dev/null
+++ b/core/java/android/os/DropBoxEntry.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2009 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 DropBoxEntry;
diff --git a/core/java/android/os/DropBoxEntry.java b/core/java/android/os/DropBoxEntry.java
new file mode 100644
index 0000000..e3816a8
--- /dev/null
+++ b/core/java/android/os/DropBoxEntry.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2009 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.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * A single entry retrieved from an {@link IDropBox} implementation.
+ * This may include a reference to a stream, so you must call
+ * {@link #close()} when you are done using it.
+ *
+ * {@pending}
+ */
+public class DropBoxEntry implements Parcelable {
+    private final String mTag;
+    private final long mTimeMillis;
+
+    private final String mText;
+    private final ParcelFileDescriptor mFileDescriptor;
+    private final int mFlags;
+
+    /** Flag value: Entry's content was deleted to save space. */
+    public static final int IS_EMPTY = 1;
+
+    /** Flag value: Content is human-readable UTF-8 text (possibly compressed). */
+    public static final int IS_TEXT = 2;
+
+    /** Flag value: Content can been decompressed with {@link GZIPOutputStream}. */
+    public static final int IS_GZIPPED = 4;
+
+    /** Create a new DropBoxEntry with the specified contents. */
+    public DropBoxEntry(String tag, long timeMillis, String text) {
+        if (tag == null || text == null) throw new NullPointerException();
+        mTag = tag;
+        mTimeMillis = timeMillis;
+        mText = text;
+        mFileDescriptor = null;
+        mFlags = IS_TEXT;
+    }
+
+    /** Create a new DropBoxEntry with the specified contents. */
+    public DropBoxEntry(String tag, long millis, File data, int flags) throws IOException {
+        if (tag == null) throw new NullPointerException();
+        if (((flags & IS_EMPTY) != 0) != (data == null)) throw new IllegalArgumentException();
+
+        mTag = tag;
+        mTimeMillis = millis;
+        mText = null;
+        mFlags = flags;
+        mFileDescriptor = data == null ? null :
+                ParcelFileDescriptor.open(data, ParcelFileDescriptor.MODE_READ_ONLY);
+    }
+
+    /** Internal constructor for CREATOR.createFromParcel(). */
+    private DropBoxEntry(String tag, long millis, Object value, int flags) {
+        if (tag == null) throw new NullPointerException();
+        if (((flags & IS_EMPTY) != 0) != (value == null)) throw new IllegalArgumentException();
+
+        mTag = tag;
+        mTimeMillis = millis;
+        mFlags = flags;
+
+        if (value == null) {
+            mText = null;
+            mFileDescriptor = null;
+        } else if (value instanceof String) {
+            if ((flags & IS_TEXT) == 0) throw new IllegalArgumentException();
+            mText = (String) value;
+            mFileDescriptor = null;
+        } else if (value instanceof ParcelFileDescriptor) {
+            mText = null;
+            mFileDescriptor = (ParcelFileDescriptor) value;
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /** Close the input stream associated with this entry. */
+    public synchronized void close() {
+        try { if (mFileDescriptor != null) mFileDescriptor.close(); } catch (IOException e) { }
+    }
+
+    /** @return the tag originally attached to the entry. */
+    public String getTag() { return mTag; }
+
+    /** @return time when the entry was originally created. */
+    public long getTimeMillis() { return mTimeMillis; }
+
+    /** @return flags describing the content returned by @{link #getInputStream()}. */
+    public int getFlags() { return mFlags & ~IS_GZIPPED; }  // getInputStream() decompresses.
+
+    /**
+     * @param maxLength of string to return (will truncate at this length).
+     * @return the uncompressed text contents of the entry, null if the entry is not text.
+     */
+    public String getText(int maxLength) {
+        if (mText != null) return mText.substring(0, Math.min(maxLength, mText.length()));
+        if ((mFlags & IS_TEXT) == 0) return null;
+
+        try {
+            InputStream stream = getInputStream();
+            if (stream == null) return null;
+            char[] buf = new char[maxLength];
+            InputStreamReader reader = new InputStreamReader(stream);
+            return new String(buf, 0, Math.max(0, reader.read(buf)));
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /** @return the uncompressed contents of the entry, or null if the contents were lost */
+    public InputStream getInputStream() throws IOException {
+        if (mText != null) return new ByteArrayInputStream(mText.getBytes("UTF8"));
+        if (mFileDescriptor == null) return null;
+        InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(mFileDescriptor);
+        return (mFlags & IS_GZIPPED) != 0 ? new GZIPInputStream(is) : is;
+    }
+
+    public static final Parcelable.Creator<DropBoxEntry> CREATOR = new Parcelable.Creator() {
+        public DropBoxEntry[] newArray(int size) { return new DropBoxEntry[size]; }
+        public DropBoxEntry createFromParcel(Parcel in) {
+            return new DropBoxEntry(
+                    in.readString(), in.readLong(), in.readValue(null), in.readInt());
+        }
+    };
+
+    public int describeContents() {
+        return mFileDescriptor != null ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mTag);
+        out.writeLong(mTimeMillis);
+        if (mFileDescriptor != null) {
+            out.writeValue(mFileDescriptor);
+        } else {
+            out.writeValue(mText);
+        }
+        out.writeInt(mFlags);
+    }
+}
diff --git a/core/java/android/os/IDropBox.aidl b/core/java/android/os/IDropBox.aidl
new file mode 100644
index 0000000..f951e52
--- /dev/null
+++ b/core/java/android/os/IDropBox.aidl
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2009 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.DropBoxEntry;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Enqueues chunks of data (from various sources -- application crashes, kernel
+ * log records, etc.).  The queue is size bounded and will drop old data if the
+ * enqueued data exceeds the maximum size.
+ *
+ * <p>This interface is implemented by a system service you can access:
+ *
+ * <pre>IDropBox.Stub.asInterface(ServiceManager.getService("dropbox"));</pre>
+ *
+ * <p>Other system services and debugging tools may scan the drop box to upload
+ * entries for processing.
+ *
+ * {@pending}
+ */
+interface IDropBox {
+    /**
+     * Stores human-readable text.  The data may be discarded eventually (or even
+     * immediately) if space is limited, or ignored entirely if the tag has been
+     * blocked (see {@link #isTagEnabled}).
+     *
+     * @param tag describing the type of entry being stored
+     * @param data value to store
+     */
+    void addText(String tag, String data);
+
+    /**
+     * Stores binary data.  The data may be ignored or discarded as with
+     * {@link #addText}.
+     *
+     * @param tag describing the type of entry being stored
+     * @param data value to store
+     * @param flags describing the data, defined in {@link DropBoxEntry}
+     */
+    void addData(String tag, in byte[] data, int flags);
+
+    /**
+     * Stores data read from a file descriptor.  The data may be ignored or
+     * discarded as with {@link #addText}.  You must close your
+     * ParcelFileDescriptor object after calling this method!
+     *
+     * @param tag describing the type of entry being stored
+     * @param data file descriptor to read from
+     * @param flags describing the data, defined in {@link DropBoxEntry}
+     */
+    void addFile(String tag, in ParcelFileDescriptor data, int flags);
+
+    /**
+     * Checks any blacklists (set in system settings) to see whether a certain
+     * tag is allowed.  Entries with disabled tags will be dropped immediately,
+     * so you can save the work of actually constructing and sending the data.
+     *
+     * @param tag that would be used in {@link #addText} or {@link #addFile}
+     * @return whether events with that tag would be accepted
+     */
+    boolean isTagEnabled(String tag);
+
+    /**
+     * Gets the next entry from the drop box *after* the specified time.
+     * Requires android.permission.READ_LOGS.
+     *
+     * @param millis time of the last entry seen
+     * @return the next entry, or null if there are no more entries
+     */
+    DropBoxEntry getNextEntry(long millis);
+
+    // TODO: It may be useful to have some sort of notification mechanism
+    // when data is added to the dropbox, for demand-driven readers --
+    // for now readers need to poll the dropbox to find new data.
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8c9581d..9bacde6 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3611,7 +3611,6 @@
          */
         public static final String SEARCH_PER_SOURCE_CONCURRENT_QUERY_LIMIT =
                 "search_per_source_concurrent_query_limit";
-
         /**
          * Flag for allowing ActivityManagerService to send ACTION_APP_ERROR intents
          * on application crashes and ANRs. If this is disabled, the crash/ANR dialog
@@ -3626,6 +3625,32 @@
         public static final String LAST_KMSG_KB = "last_kmsg_kb";
 
         /**
+         * Maximum age of entries kept by {@link android.os.IDropBox}.
+         */
+        public static final String DROPBOX_AGE_SECONDS =
+                "dropbox_age_seconds";
+        /**
+         * Maximum amount of disk space used by {@link android.os.IDropBox} no matter what.
+         */
+        public static final String DROPBOX_QUOTA_KB =
+                "dropbox_quota_kb";
+        /**
+         * Percent of free disk (excluding reserve) which {@link android.os.IDropBox} will use.
+         */
+        public static final String DROPBOX_QUOTA_PERCENT =
+                "dropbox_quota_percent";
+        /**
+         * Percent of total disk which {@link android.os.IDropBox} will never dip into.
+         */
+        public static final String DROPBOX_RESERVE_PERCENT =
+                "dropbox_reserve_percent";
+        /**
+         * Prefix for per-tag dropbox disable/enable settings.
+         */
+        public static final String DROPBOX_TAG_PREFIX =
+                "dropbox:";
+
+        /**
          * @deprecated
          * @hide
          */
diff --git a/services/java/com/android/server/DropBoxService.java b/services/java/com/android/server/DropBoxService.java
new file mode 100644
index 0000000..3a4c3ac
--- /dev/null
+++ b/services/java/com/android/server/DropBoxService.java
@@ -0,0 +1,725 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.DropBoxEntry;
+import android.os.IDropBox;
+import android.os.ParcelFileDescriptor;
+import android.os.StatFs;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.text.format.DateFormat;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * Implementation of {@link IDropBox} using the filesystem.
+ *
+ * {@hide}
+ */
+public final class DropBoxService extends IDropBox.Stub {
+    private static final String TAG = "DropBoxService";
+    private static final int DEFAULT_RESERVE_PERCENT = 10;
+    private static final int DEFAULT_QUOTA_PERCENT = 10;
+    private static final int DEFAULT_QUOTA_KB = 5 * 1024;
+    private static final int DEFAULT_AGE_SECONDS = 3 * 86400;
+    private static final int QUOTA_RESCAN_MILLIS = 5000;
+
+    // TODO: This implementation currently uses one file per entry, which is
+    // inefficient for smallish entries -- consider using a single queue file
+    // per tag (or even globally) instead.
+
+    // The cached context and derived objects
+
+    private final Context mContext;
+    private final ContentResolver mContentResolver;
+    private final File mDropBoxDir;
+
+    // Accounting of all currently written log files (set in init()).
+
+    private FileList mAllFiles = null;
+    private HashMap<String, FileList> mFilesByTag = null;
+
+    // Various bits of disk information
+
+    private StatFs mStatFs = null;
+    private int mBlockSize = 0;
+    private int mCachedQuotaBlocks = 0;  // Space we can use: computed from free space, etc.
+    private long mCachedQuotaUptimeMillis = 0;
+
+    // Ensure that all log entries have a unique timestamp
+    private long mLastTimestamp = 0;
+
+    /** Receives events that might indicate a need to clean up files. */
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mCachedQuotaUptimeMillis = 0;  // Force a re-check of quota size
+            try {
+                init();
+                trimToFit();
+            } catch (IOException e) {
+                Log.e(TAG, "Can't init", e);
+            }
+        }
+    };
+
+    /**
+     * Creates an instance of managed drop box storage.  Normally there is one of these
+     * run by the system, but others can be created for testing and other purposes.
+     *
+     * @param context to use for receiving free space & gservices intents
+     * @param path to store drop box entries in
+     */
+    public DropBoxService(Context context, File path) {
+        mDropBoxDir = path;
+
+        // Set up intent receivers
+        mContext = context;
+        mContentResolver = context.getContentResolver();
+        context.registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW));
+        context.registerReceiver(mReceiver, new IntentFilter(Settings.Gservices.CHANGED_ACTION));
+
+        // The real work gets done lazily in init() -- that way service creation always
+        // succeeds, and things like disk problems cause individual method failures.
+    }
+
+    /** Unregisters broadcast receivers and any other hooks -- for test instances */
+    public void stop() {
+        mContext.unregisterReceiver(mReceiver);
+    }
+
+    public void addText(String tag, String data) {
+        addData(tag, data.getBytes(), DropBoxEntry.IS_TEXT);
+    }
+
+    public void addData(String tag, byte[] data, int flags) {
+        File temp = null;
+        OutputStream out = null;
+        try {
+            if ((flags & DropBoxEntry.IS_EMPTY) != 0) throw new IllegalArgumentException();
+
+            init();
+            if (!isTagEnabled(tag)) return;
+
+            long max = trimToFit();
+            if (data.length > max) {
+                Log.w(TAG, "Dropping: " + tag + " (" + data.length + " > " + max + " bytes)");
+                // Pass temp = null to createEntry() to leave a tombstone
+            } else {
+                temp = new File(mDropBoxDir, "drop" + Thread.currentThread().getId() + ".tmp");
+                out = new FileOutputStream(temp);
+                if (data.length > mBlockSize && ((flags & DropBoxEntry.IS_GZIPPED) == 0)) {
+                    flags = flags | DropBoxEntry.IS_GZIPPED;
+                    out = new GZIPOutputStream(out);
+                }
+                out.write(data);
+                out.close();
+                out = null;
+            }
+
+            createEntry(temp, tag, flags);
+            temp = null;
+        } catch (IOException e) {
+            Log.e(TAG, "Can't write: " + tag, e);
+        } finally {
+            try { if (out != null) out.close(); } catch (IOException e) {}
+            if (temp != null) temp.delete();
+        }
+    }
+
+    public void addFile(String tag, ParcelFileDescriptor data, int flags) {
+        File temp = null;
+        OutputStream output = null;
+        try {
+            if ((flags & DropBoxEntry.IS_EMPTY) != 0) throw new IllegalArgumentException();
+
+            init();
+            if (!isTagEnabled(tag)) return;
+            long max = trimToFit();
+            long lastTrim = System.currentTimeMillis();
+
+            byte[] buffer = new byte[mBlockSize];
+            FileInputStream input = new FileInputStream(data.getFileDescriptor());
+
+            // First, accumulate up to one block worth of data in memory before
+            // deciding whether to compress the data or not.
+
+            int read = 0;
+            while (read < buffer.length) {
+                int n = input.read(buffer, read, buffer.length - read);
+                if (n <= 0) break;
+                read += n;
+            }
+
+            // If we have at least one block, compress it -- otherwise, just write
+            // the data in uncompressed form.
+
+            temp = new File(mDropBoxDir, "drop" + Thread.currentThread().getId() + ".tmp");
+            output = new FileOutputStream(temp);
+            if (read == buffer.length && ((flags & DropBoxEntry.IS_GZIPPED) == 0)) {
+                output = new GZIPOutputStream(output);
+                flags = flags | DropBoxEntry.IS_GZIPPED;
+            }
+
+            do {
+                output.write(buffer, 0, read);
+
+                long now = System.currentTimeMillis();
+                if (now - lastTrim > 30 * 1000) {
+                    max = trimToFit();  // In case data dribbles in slowly
+                    lastTrim = now;
+                }
+
+                read = input.read(buffer);
+                if (read <= 0) {
+                    output.close();  // Get a final size measurement
+                    output = null;
+                } else {
+                    output.flush();  // So the size measurement is pseudo-reasonable
+                }
+
+                long len = temp.length();
+                if (len > max) {
+                    Log.w(TAG, "Dropping: " + tag + " (" + temp.length() + " > " + max + " bytes)");
+                    temp.delete();
+                    temp = null;  // Pass temp = null to createEntry() to leave a tombstone
+                    break;
+                }
+            } while (read > 0);
+
+            createEntry(temp, tag, flags);
+            temp = null;
+        } catch (IOException e) {
+            Log.e(TAG, "Can't write: " + tag, e);
+        } finally {
+            try { if (output != null) output.close(); } catch (IOException e) {}
+            try { data.close(); } catch (IOException e) {}
+            if (temp != null) temp.delete();
+        }
+    }
+
+    public boolean isTagEnabled(String tag) {
+        return !"disabled".equals(Settings.Gservices.getString(
+                mContentResolver, Settings.Gservices.DROPBOX_TAG_PREFIX + tag));
+    }
+
+    public synchronized DropBoxEntry getNextEntry(long millis) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.READ_LOGS)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("READ_LOGS permission required");
+        }
+
+        try {
+            init();
+        } catch (IOException e) {
+            Log.e(TAG, "Can't init", e);
+            return null;
+        }
+
+        for (EntryFile entry : mAllFiles.contents.tailSet(new EntryFile(millis + 1))) {
+            if (entry.tag == null) continue;
+            try {
+                File file = (entry.flags & DropBoxEntry.IS_EMPTY) != 0 ? null : entry.file;
+                return new DropBoxEntry(entry.tag, entry.timestampMillis, file, entry.flags);
+            } catch (IOException e) {
+                Log.e(TAG, "Can't read: " + entry.file, e);
+                // Continue to next file
+            }
+        }
+
+        return null;
+    }
+
+    public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: Can't dump DropBoxService");
+            return;
+        }
+
+        try {
+            init();
+        } catch (IOException e) {
+            pw.println("Can't initialize: " + e);
+            Log.e(TAG, "Can't init", e);
+            return;
+        }
+
+        boolean doPrint = false, doFile = false;
+        ArrayList<String> searchArgs = new ArrayList<String>();
+        for (int i = 0; args != null && i < args.length; i++) {
+            if (args[i].equals("-p") || args[i].equals("--print")) {
+                doPrint = true;
+            } else if (args[i].equals("-f") || args[i].equals("--file")) {
+                doFile = true;
+            } else if (args[i].startsWith("-")) {
+                pw.print("Unknown argument: ");
+                pw.println(args[i]);
+            } else {
+                searchArgs.add(args[i]);
+            }
+        }
+
+        pw.format("Drop box contents: %d entries", mAllFiles.contents.size());
+        pw.println();
+
+        if (!searchArgs.isEmpty()) {
+            pw.print("Searching for:");
+            for (String a : searchArgs) pw.format(" %s", a);
+            pw.println();
+        }
+
+        int numFound = 0;
+        pw.println();
+        for (EntryFile entry : mAllFiles.contents) {
+            String date = new Formatter().format("%s.%03d",
+                    DateFormat.format("yyyy-MM-dd kk:mm:ss", entry.timestampMillis),
+                    entry.timestampMillis % 1000).toString();
+
+            boolean match = true;
+            for (String a: searchArgs) match = match && (date.contains(a) || a.equals(entry.tag));
+            if (!match) continue;
+
+            numFound++;
+            pw.print(date);
+            pw.print(" ");
+            pw.print(entry.tag == null ? "(no tag)" : entry.tag);
+            if (entry.file == null) {
+                pw.println(" (no file)");
+                continue;
+            } else if ((entry.flags & DropBoxEntry.IS_EMPTY) != 0) {
+                pw.println(" (contents lost)");
+                continue;
+            } else {
+                pw.print((entry.flags & DropBoxEntry.IS_GZIPPED) != 0 ? " (comopressed " : " (");
+                pw.print((entry.flags & DropBoxEntry.IS_TEXT) != 0 ? "text" : "data");
+                pw.format(", %d bytes)", entry.file.length());
+                pw.println();
+            }
+
+            if (doFile || (doPrint && (entry.flags & DropBoxEntry.IS_TEXT) == 0)) {
+                if (!doPrint) pw.print("    ");
+                pw.println(entry.file.getPath());
+            }
+
+            if ((entry.flags & DropBoxEntry.IS_TEXT) != 0 && (doPrint || !doFile)) {
+                DropBoxEntry dbe = null;
+                try {
+                    dbe = new DropBoxEntry(
+                             entry.tag, entry.timestampMillis, entry.file, entry.flags);
+
+                    if (doPrint) {
+                        InputStreamReader r = new InputStreamReader(dbe.getInputStream());
+                        char[] buf = new char[4096];
+                        boolean newline = false;
+                        for (;;) {
+                            int n = r.read(buf);
+                            if (n <= 0) break;
+                            pw.write(buf, 0, n);
+                            newline = (buf[n - 1] == '\n');
+                        }
+                        if (!newline) pw.println();
+                    } else {
+                        String text = dbe.getText(70);
+                        boolean truncated = (text.length() == 70);
+                        pw.print("    ");
+                        pw.print(text.trim().replace('\n', '/'));
+                        if (truncated) pw.print(" ...");
+                        pw.println();
+                    }
+                } catch (IOException e) {
+                    pw.print("*** ");
+                    pw.println(e.toString());
+                    Log.e(TAG, "Can't read: " + entry.file, e);
+                } finally {
+                    if (dbe != null) dbe.close();
+                }
+            }
+
+            if (doPrint) pw.println();
+        }
+
+        if (numFound == 0) pw.println("(No entries found.)");
+
+        if (args == null || args.length == 0) {
+            if (!doPrint) pw.println();
+            pw.println("Usage: dumpsys dropbox [--print|--file] [YYYY-mm-dd] [HH:MM:SS.SSS] [tag]");
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    /** Chronologically sorted list of {@link #EntryFile} */
+    private static final class FileList implements Comparable<FileList> {
+        public int blocks = 0;
+        public final TreeSet<EntryFile> contents = new TreeSet<EntryFile>();
+
+        /** Sorts bigger FileList instances before smaller ones. */
+        public final int compareTo(FileList o) {
+            if (blocks != o.blocks) return o.blocks - blocks;
+            if (this == o) return 0;
+            if (hashCode() < o.hashCode()) return -1;
+            if (hashCode() > o.hashCode()) return 1;
+            return 0;
+        }
+    }
+
+    /** Metadata describing an on-disk log file. */
+    private static final class EntryFile implements Comparable<EntryFile> {
+        public final String tag;
+        public final long timestampMillis;
+        public final int flags;
+        public final File file;
+        public final int blocks;
+
+        /** Sorts earlier EntryFile instances before later ones. */
+        public final int compareTo(EntryFile o) {
+            if (timestampMillis < o.timestampMillis) return -1;
+            if (timestampMillis > o.timestampMillis) return 1;
+            if (file != null && o.file != null) return file.compareTo(o.file);
+            if (o.file != null) return -1;
+            if (file != null) return 1;
+            if (this == o) return 0;
+            if (hashCode() < o.hashCode()) return -1;
+            if (hashCode() > o.hashCode()) return 1;
+            return 0;
+        }
+
+        /**
+         * Moves an existing temporary file to a new log filename.
+         * @param temp file to rename
+         * @param dir to store file in
+         * @param tag to use for new log file name
+         * @param timestampMillis of log entry
+         * @param flags for the entry data (from {@link DropBoxEntry})
+         * @param blockSize to use for space accounting
+         * @throws IOException if the file can't be moved
+         */
+        public EntryFile(File temp, File dir, String tag,long timestampMillis,
+                         int flags, int blockSize) throws IOException {
+            if ((flags & DropBoxEntry.IS_EMPTY) != 0) throw new IllegalArgumentException();
+
+            this.tag = tag;
+            this.timestampMillis = timestampMillis;
+            this.flags = flags;
+            this.file = new File(dir, Uri.encode(tag) + "@" + timestampMillis +
+                    ((flags & DropBoxEntry.IS_TEXT) != 0 ? ".txt" : ".dat") +
+                    ((flags & DropBoxEntry.IS_GZIPPED) != 0 ? ".gz" : ""));
+
+            if (!temp.renameTo(this.file)) {
+                throw new IOException("Can't rename " + temp + " to " + this.file);
+            }
+            this.blocks = (int) ((this.file.length() + blockSize - 1) / blockSize);
+        }
+
+        /**
+         * Creates a zero-length tombstone for a file whose contents were lost.
+         * @param dir to store file in
+         * @param tag to use for new log file name
+         * @param timestampMillis of log entry
+         * @throws IOException if the file can't be created.
+         */
+        public EntryFile(File dir, String tag, long timestampMillis) throws IOException {
+            this.tag = tag;
+            this.timestampMillis = timestampMillis;
+            this.flags = DropBoxEntry.IS_EMPTY;
+            this.file = new File(dir, Uri.encode(tag) + "@" + timestampMillis + ".lost");
+            this.blocks = 0;
+            new FileOutputStream(this.file).close();
+        }
+
+        /**
+         * Extracts metadata from an existing on-disk log filename.
+         * @param file name of existing log file
+         * @param blockSize to use for space accounting
+         */
+        public EntryFile(File file, int blockSize) {
+            this.file = file;
+            this.blocks = (int) ((this.file.length() + blockSize - 1) / blockSize);
+
+            String name = file.getName();
+            int at = name.lastIndexOf('@');
+            if (at < 0) {
+                this.tag = null;
+                this.timestampMillis = 0;
+                this.flags = DropBoxEntry.IS_EMPTY;
+                return;
+            }
+
+            int flags = 0;
+            this.tag = Uri.decode(name.substring(0, at));
+            if (name.endsWith(".gz")) {
+                flags |= DropBoxEntry.IS_GZIPPED;
+                name = name.substring(0, name.length() - 3);
+            }
+            if (name.endsWith(".lost")) {
+                flags |= DropBoxEntry.IS_EMPTY;
+                name = name.substring(at + 1, name.length() - 5);
+            } else if (name.endsWith(".txt")) {
+                flags |= DropBoxEntry.IS_TEXT;
+                name = name.substring(at + 1, name.length() - 4);
+            } else if (name.endsWith(".dat")) {
+                name = name.substring(at + 1, name.length() - 4);
+            } else {
+                this.flags = DropBoxEntry.IS_EMPTY;
+                this.timestampMillis = 0;
+                return;
+            }
+            this.flags = flags;
+
+            long millis;
+            try { millis = Long.valueOf(name); } catch (NumberFormatException e) { millis = 0; }
+            this.timestampMillis = millis;
+        }
+
+        /**
+         * Creates a EntryFile object with only a timestamp for comparison purposes.
+         * @param timestampMillis to compare with.
+         */
+        public EntryFile(long millis) {
+            this.tag = null;
+            this.timestampMillis = millis;
+            this.flags = DropBoxEntry.IS_EMPTY;
+            this.file = null;
+            this.blocks = 0;
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    /** If never run before, scans disk contents to build in-memory tracking data. */
+    private synchronized void init() throws IOException {
+        if (mStatFs == null) {
+            if (!mDropBoxDir.isDirectory() && !mDropBoxDir.mkdirs()) {
+                throw new IOException("Can't mkdir: " + mDropBoxDir);
+            }
+            try {
+                mStatFs = new StatFs(mDropBoxDir.getPath());
+                mBlockSize = mStatFs.getBlockSize();
+            } catch (IllegalArgumentException e) {  // StatFs throws this on error
+                throw new IOException("Can't statfs: " + mDropBoxDir);
+            }
+        }
+
+        if (mAllFiles == null) {
+            File[] files = mDropBoxDir.listFiles();
+            if (files == null) throw new IOException("Can't list files: " + mDropBoxDir);
+
+            mAllFiles = new FileList();
+            mFilesByTag = new HashMap<String, FileList>();
+
+            // Scan pre-existing files.
+            for (File file : files) {
+                if (file.getName().endsWith(".tmp")) {
+                    Log.i(TAG, "Cleaning temp file: " + file);
+                    file.delete();
+                    continue;
+                }
+
+                EntryFile entry = new EntryFile(file, mBlockSize);
+                if (entry.tag == null) {
+                    Log.w(TAG, "Unrecognized file: " + file);
+                    continue;
+                } else if (entry.timestampMillis == 0) {
+                    Log.w(TAG, "Invalid filename: " + file);
+                    file.delete();
+                    continue;
+                }
+
+                enrollEntry(entry);
+            }
+        }
+    }
+
+    /** Adds a disk log file to in-memory tracking for accounting and enumeration. */
+    private synchronized void enrollEntry(EntryFile entry) {
+        mAllFiles.contents.add(entry);
+        mAllFiles.blocks += entry.blocks;
+
+        // mFilesByTag is used for trimming, so don't list empty files.
+        // (Zero-length/lost files are trimmed by date from mAllFiles.)
+
+        if (entry.tag != null && entry.file != null && entry.blocks > 0) {
+            FileList tagFiles = mFilesByTag.get(entry.tag);
+            if (tagFiles == null) {
+                tagFiles = new FileList();
+                mFilesByTag.put(entry.tag, tagFiles);
+            }
+            tagFiles.contents.add(entry);
+            tagFiles.blocks += entry.blocks;
+        }
+    }
+
+    /** Moves a temporary file to a final log filename and enrolls it. */
+    private synchronized void createEntry(File temp, String tag, int flags) throws IOException {
+        long t = System.currentTimeMillis();
+
+        // Require each entry to have a unique timestamp; if there are entries
+        // >10sec in the future (due to clock skew), drag them back to avoid
+        // keeping them around forever.
+
+        SortedSet<EntryFile> tail = mAllFiles.contents.tailSet(new EntryFile(t + 10000));
+        EntryFile[] future = null;
+        if (!tail.isEmpty()) {
+            future = tail.toArray(new EntryFile[tail.size()]);
+            tail.clear();  // Remove from mAllFiles
+        }
+
+        if (!mAllFiles.contents.isEmpty()) {
+            t = Math.max(t, mAllFiles.contents.last().timestampMillis + 1);
+        }
+
+        if (future != null) {
+            for (EntryFile late : future) {
+                mAllFiles.blocks -= late.blocks;
+                FileList tagFiles = mFilesByTag.get(late.tag);
+                if (tagFiles.contents.remove(late)) tagFiles.blocks -= late.blocks;
+                if ((late.flags & DropBoxEntry.IS_EMPTY) == 0) {
+                    enrollEntry(new EntryFile(
+                            late.file, mDropBoxDir, late.tag, t++, late.flags, mBlockSize));
+                } else {
+                    enrollEntry(new EntryFile(mDropBoxDir, late.tag, t++));
+                }
+            }
+        }
+
+        if (temp == null) {
+            enrollEntry(new EntryFile(mDropBoxDir, tag, t));
+        } else {
+            enrollEntry(new EntryFile(temp, mDropBoxDir, tag, t, flags, mBlockSize));
+        }
+    }
+
+    /**
+     * Trims the files on disk to make sure they aren't using too much space.
+     * @return the overall quota for storage (in bytes)
+     */
+    private synchronized long trimToFit() {
+        // Expunge aged items (including tombstones marking deleted data).
+
+        int ageSeconds = Settings.Gservices.getInt(mContentResolver,
+                Settings.Gservices.DROPBOX_AGE_SECONDS, DEFAULT_AGE_SECONDS);
+        long cutoffMillis = System.currentTimeMillis() - ageSeconds * 1000;
+        while (!mAllFiles.contents.isEmpty()) {
+            EntryFile entry = mAllFiles.contents.first();
+            if (entry.timestampMillis > cutoffMillis) break;
+
+            FileList tag = mFilesByTag.get(entry.tag);
+            if (tag != null && tag.contents.remove(entry)) tag.blocks -= entry.blocks;
+            if (mAllFiles.contents.remove(entry)) mAllFiles.blocks -= entry.blocks;
+            if (entry.file != null) entry.file.delete();
+        }
+
+        // Compute overall quota (a fraction of available free space) in blocks.
+        // The quota changes dynamically based on the amount of free space;
+        // that way when lots of data is available we can use it, but we'll get
+        // out of the way if storage starts getting tight.
+
+        long uptimeMillis = SystemClock.uptimeMillis();
+        if (uptimeMillis > mCachedQuotaUptimeMillis + QUOTA_RESCAN_MILLIS) {
+            int quotaPercent = Settings.Gservices.getInt(mContentResolver,
+                    Settings.Gservices.DROPBOX_QUOTA_PERCENT, DEFAULT_QUOTA_PERCENT);
+            int reservePercent = Settings.Gservices.getInt(mContentResolver,
+                    Settings.Gservices.DROPBOX_RESERVE_PERCENT, DEFAULT_RESERVE_PERCENT);
+            int quotaKb = Settings.Gservices.getInt(mContentResolver,
+                    Settings.Gservices.DROPBOX_QUOTA_KB, DEFAULT_QUOTA_KB);
+
+            mStatFs.restat(mDropBoxDir.getPath());
+            int available = mStatFs.getAvailableBlocks();
+            int nonreserved = available - mStatFs.getBlockCount() * reservePercent / 100;
+            int maximum = quotaKb * 1024 / mBlockSize;
+            mCachedQuotaBlocks = Math.min(maximum, Math.max(0, nonreserved * quotaPercent / 100));
+            mCachedQuotaUptimeMillis = uptimeMillis;
+        }
+
+        // If we're using too much space, delete old items to make room.
+        //
+        // We trim each tag independently (this is why we keep per-tag lists).
+        // Space is "fairly" shared between tags -- they are all squeezed
+        // equally until enough space is reclaimed.
+        //
+        // A single circular buffer (a la logcat) would be simpler, but this
+        // way we can handle fat/bursty data (like 1MB+ bugreports, 300KB+
+        // kernel crash dumps, and 100KB+ ANR reports) without swamping small,
+        // well-behaved data // streams (event statistics, profile data, etc).
+        //
+        // Deleted files are replaced with zero-length tombstones to mark what
+        // was lost.  Tombstones are expunged by age (see above).
+
+        if (mAllFiles.blocks > mCachedQuotaBlocks) {
+            Log.i(TAG, "Usage (" + mAllFiles.blocks + ") > Quota (" + mCachedQuotaBlocks + ")");
+
+            // Find a fair share amount of space to limit each tag
+            int unsqueezed = mAllFiles.blocks, squeezed = 0;
+            TreeSet<FileList> tags = new TreeSet<FileList>(mFilesByTag.values());
+            for (FileList tag : tags) {
+                if (squeezed > 0 && tag.blocks <= (mCachedQuotaBlocks - unsqueezed) / squeezed) {
+                    break;
+                }
+                unsqueezed -= tag.blocks;
+                squeezed++;
+            }
+            int tagQuota = (mCachedQuotaBlocks - unsqueezed) / squeezed;
+
+            // Remove old items from each tag until it meets the per-tag quota.
+            for (FileList tag : tags) {
+                if (mAllFiles.blocks < mCachedQuotaBlocks) break;
+                while (tag.blocks > tagQuota && !tag.contents.isEmpty()) {
+                    EntryFile entry = tag.contents.first();
+                    if (tag.contents.remove(entry)) tag.blocks -= entry.blocks;
+                    if (mAllFiles.contents.remove(entry)) mAllFiles.blocks -= entry.blocks;
+
+                    try {
+                        if (entry.file != null) entry.file.delete();
+                        enrollEntry(new EntryFile(mDropBoxDir, entry.tag, entry.timestampMillis));
+                    } catch (IOException e) {
+                        Log.e(TAG, "Can't write tombstone file", e);
+                    }
+                }
+            }
+        }
+
+        return mCachedQuotaBlocks * mBlockSize;
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b8cf844..1a7416a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -43,6 +43,7 @@
 import android.util.Log;
 import android.accounts.AccountManagerService;
 
+import java.io.File;
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -294,6 +295,14 @@
             }
 
             try {
+                Log.i(TAG, "DropBox Service");
+                ServiceManager.addService("dropbox",
+                        new DropBoxService(context, new File("/data/system/dropbox")));
+            } catch (Throwable e) {
+                Log.e(TAG, "Failure starting DropBox Service", e);
+            }
+
+            try {
                 Log.i(TAG, "Checkin Service");
                 Intent intent = new Intent().setComponent(new ComponentName(
                         "com.google.android.server.checkin",
diff --git a/tests/AndroidTests/Android.mk b/tests/AndroidTests/Android.mk
index ced796a..757044f 100644
--- a/tests/AndroidTests/Android.mk
+++ b/tests/AndroidTests/Android.mk
@@ -3,7 +3,7 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := framework-tests android.test.runner
+LOCAL_JAVA_LIBRARIES := framework-tests android.test.runner services
 
 LOCAL_STATIC_JAVA_LIBRARIES := googlelogin-client
 
diff --git a/tests/AndroidTests/AndroidManifest.xml b/tests/AndroidTests/AndroidManifest.xml
index d94327a..786178c 100644
--- a/tests/AndroidTests/AndroidManifest.xml
+++ b/tests/AndroidTests/AndroidManifest.xml
@@ -35,27 +35,27 @@
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.READ_SMS"/>
-    <uses-permission android:name="android.permission.WRITE_SMS"/>
-    <uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
     <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
     <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
+    <uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
     <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.WRITE_GSERVICES" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <uses-permission android:name="com.android.unit_tests.permission.TEST_GRANTED" />
-
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.READ_LOGS"/>
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.READ_SMS"/>
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_GSERVICES" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_SMS"/>
+    <uses-permission android:name="com.android.unit_tests.permission.TEST_GRANTED" />
+    <uses-permission android:name="com.google.android.googleapps.permission.ACCESS_GOOGLE_PASSWORD" />
     <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
     <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.ALL_SERVICES" />
-    <uses-permission android:name="com.google.android.googleapps.permission.ACCESS_GOOGLE_PASSWORD" />
+
     <!-- InstrumentationTestRunner for AndroidTests -->
     <instrumentation android:name="android.test.InstrumentationTestRunner"
                      android:targetPackage="com.android.unit_tests"
diff --git a/tests/AndroidTests/src/com/android/unit_tests/DropBoxTest.java b/tests/AndroidTests/src/com/android/unit_tests/DropBoxTest.java
new file mode 100644
index 0000000..77ebf8d
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/DropBoxTest.java
@@ -0,0 +1,479 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.unit_tests;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.DropBoxEntry;
+import android.os.IDropBox;
+import android.os.ParcelFileDescriptor;
+import android.os.ServiceManager;
+import android.os.StatFs;
+import android.provider.Settings;
+import android.test.AndroidTestCase;
+
+import com.android.server.DropBoxService;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.util.Random;
+import java.util.zip.GZIPOutputStream;
+
+/** Test {@link IDropBox} functionality. */
+public class DropBoxTest extends AndroidTestCase {
+    public void tearDown() throws Exception {
+        Intent override = new Intent(Settings.Gservices.OVERRIDE_ACTION);
+        override.putExtra(Settings.Gservices.DROPBOX_AGE_SECONDS, "");
+        override.putExtra(Settings.Gservices.DROPBOX_QUOTA_KB, "");
+        override.putExtra(Settings.Gservices.DROPBOX_TAG_PREFIX + "DropBoxTest", "");
+        waitForBroadcast(override);
+    }
+
+    public void testAddText() throws Exception {
+        IDropBox dropbox = IDropBox.Stub.asInterface(ServiceManager.getService("dropbox"));
+        long before = System.currentTimeMillis();
+        Thread.sleep(5);
+        dropbox.addText("DropBoxTest", "TEST0");
+        Thread.sleep(5);
+        long between = System.currentTimeMillis();
+        Thread.sleep(5);
+        dropbox.addText("DropBoxTest", "TEST1");
+        dropbox.addText("DropBoxTest", "TEST2");
+        Thread.sleep(5);
+        long after = System.currentTimeMillis();
+
+        DropBoxEntry e0 = getNextTestEntry(dropbox, before);
+        DropBoxEntry e1 = getNextTestEntry(dropbox, e0.getTimeMillis());
+        DropBoxEntry e2 = getNextTestEntry(dropbox, e1.getTimeMillis());
+        assertTrue(null == getNextTestEntry(dropbox, e2.getTimeMillis()));
+
+        assertTrue(e0.getTimeMillis() > before);
+        assertTrue(e0.getTimeMillis() < between);
+        assertTrue(e1.getTimeMillis() > between);
+        assertTrue(e1.getTimeMillis() < e2.getTimeMillis());
+        assertTrue(e2.getTimeMillis() < after);
+
+        assertEquals("TEST0", e0.getText(80));
+        assertEquals("TEST1", e1.getText(80));
+        assertEquals("TES", e2.getText(3));
+
+        e0.close();
+        e1.close();
+        e2.close();
+    }
+
+    public void testAddData() throws Exception {
+        IDropBox dropbox = IDropBox.Stub.asInterface(ServiceManager.getService("dropbox"));
+        long before = System.currentTimeMillis();
+        dropbox.addData("DropBoxTest", "TEST".getBytes(), 0);
+        long after = System.currentTimeMillis();
+
+        DropBoxEntry e = getNextTestEntry(dropbox, before);
+        assertTrue(null == getNextTestEntry(dropbox, e.getTimeMillis()));
+
+        assertEquals("DropBoxTest", e.getTag());
+        assertTrue(e.getTimeMillis() >= before);
+        assertEquals(0, e.getFlags());
+        assertTrue(null == e.getText(80));
+
+        byte[] buf = new byte[80];
+        assertEquals("TEST", new String(buf, 0, e.getInputStream().read(buf)));
+
+        e.close();
+    }
+
+    public void testAddFile() throws Exception {
+        File dir = getEmptyDir("testAddFile");
+        long before = System.currentTimeMillis();
+
+        File f0 = new File(dir, "f0.txt");
+        File f1 = new File(dir, "f1.txt.gz");
+        File f2 = new File(dir, "f2.dat");
+        File f3 = new File(dir, "f2.dat.gz");
+
+        FileWriter w0 = new FileWriter(f0);
+        GZIPOutputStream gz1 = new GZIPOutputStream(new FileOutputStream(f1));
+        FileOutputStream os2 = new FileOutputStream(f2);
+        GZIPOutputStream gz3 = new GZIPOutputStream(new FileOutputStream(f3));
+
+        w0.write("FILE0");
+        gz1.write("FILE1".getBytes());
+        os2.write("DATA2".getBytes());
+        gz3.write("DATA3".getBytes());
+
+        w0.close();
+        gz1.close();
+        os2.close();
+        gz3.close();
+
+        IDropBox dropbox = IDropBox.Stub.asInterface(ServiceManager.getService("dropbox"));
+        int mode = ParcelFileDescriptor.MODE_READ_ONLY;
+
+        ParcelFileDescriptor pfd0 = ParcelFileDescriptor.open(f0, mode);
+        ParcelFileDescriptor pfd1 = ParcelFileDescriptor.open(f1, mode);
+        ParcelFileDescriptor pfd2 = ParcelFileDescriptor.open(f2, mode);
+        ParcelFileDescriptor pfd3 = ParcelFileDescriptor.open(f3, mode);
+
+        dropbox.addFile("DropBoxTest", pfd0, DropBoxEntry.IS_TEXT);
+        dropbox.addFile("DropBoxTest", pfd1, DropBoxEntry.IS_TEXT | DropBoxEntry.IS_GZIPPED);
+        dropbox.addFile("DropBoxTest", pfd2, 0);
+        dropbox.addFile("DropBoxTest", pfd3, DropBoxEntry.IS_GZIPPED);
+
+        pfd0.close();
+        pfd1.close();
+        pfd2.close();
+        pfd3.close();
+
+        DropBoxEntry e0 = getNextTestEntry(dropbox, before);
+        DropBoxEntry e1 = getNextTestEntry(dropbox, e0.getTimeMillis());
+        DropBoxEntry e2 = getNextTestEntry(dropbox, e1.getTimeMillis());
+        DropBoxEntry e3 = getNextTestEntry(dropbox, e2.getTimeMillis());
+        assertTrue(null == getNextTestEntry(dropbox, e3.getTimeMillis()));
+
+        assertTrue(e0.getTimeMillis() > before);
+        assertTrue(e1.getTimeMillis() > e0.getTimeMillis());
+        assertTrue(e2.getTimeMillis() > e1.getTimeMillis());
+        assertTrue(e3.getTimeMillis() > e2.getTimeMillis());
+
+        assertEquals(DropBoxEntry.IS_TEXT, e0.getFlags());
+        assertEquals(DropBoxEntry.IS_TEXT, e1.getFlags());
+        assertEquals(0, e2.getFlags());
+        assertEquals(0, e3.getFlags());
+
+        assertEquals("FILE0", e0.getText(80));
+
+        byte[] buf1 = new byte[80];
+        assertEquals("FILE1", new String(buf1, 0, e1.getInputStream().read(buf1)));
+
+        assertTrue(null == e2.getText(80));
+        byte[] buf2 = new byte[80];
+        assertEquals("DATA2", new String(buf2, 0, e2.getInputStream().read(buf2)));
+
+        assertTrue(null == e3.getText(80));
+        byte[] buf3 = new byte[80];
+        assertEquals("DATA3", new String(buf3, 0, e3.getInputStream().read(buf3)));
+
+        e0.close();
+        e1.close();
+        e2.close();
+        e3.close();
+    }
+
+    public void testAddEntriesInTheFuture() throws Exception {
+        File dir = getEmptyDir("testAddEntriesInTheFuture");
+        long before = System.currentTimeMillis();
+
+        // Near future: should be allowed to persist
+        FileWriter w0 = new FileWriter(new File(dir, "DropBoxTest@" + (before + 5000) + ".txt"));
+        w0.write("FUTURE0");
+        w0.close();
+
+        // Far future: should be collapsed
+        FileWriter w1 = new FileWriter(new File(dir, "DropBoxTest@" + (before + 100000) + ".txt"));
+        w1.write("FUTURE1");
+        w1.close();
+
+        // Another far future item, this one gzipped
+        File f2 = new File(dir, "DropBoxTest@" + (before + 100001) + ".txt.gz");
+        GZIPOutputStream gz2 = new GZIPOutputStream(new FileOutputStream(f2));
+        gz2.write("FUTURE2".getBytes());
+        gz2.close();
+
+        // Tombstone in the far future
+        new FileOutputStream(new File(dir, "DropBoxTest@" + (before + 100002) + ".lost")).close();
+
+        DropBoxService dropbox = new DropBoxService(getContext(), dir);
+
+        // Until a write, the timestamps are taken at face value
+        DropBoxEntry e0 = getNextTestEntry(dropbox, before);
+        DropBoxEntry e1 = getNextTestEntry(dropbox, e0.getTimeMillis());
+        DropBoxEntry e2 = getNextTestEntry(dropbox, e1.getTimeMillis());
+        DropBoxEntry e3 = getNextTestEntry(dropbox, e2.getTimeMillis());
+        assertTrue(null == getNextTestEntry(dropbox, e3.getTimeMillis()));
+
+        assertEquals("FUTURE0", e0.getText(80));
+        assertEquals("FUTURE1", e1.getText(80));
+        assertEquals("FUTURE2", e2.getText(80));
+        assertEquals(null, e3.getText(80));
+
+        assertEquals(before + 5000, e0.getTimeMillis());
+        assertEquals(before + 100000, e1.getTimeMillis());
+        assertEquals(before + 100001, e2.getTimeMillis());
+        assertEquals(before + 100002, e3.getTimeMillis());
+
+        e0.close();
+        e1.close();
+        e2.close();
+        e3.close();
+
+        // Write something to force a collapse
+        dropbox.addText("NotDropBoxTest", "FUTURE");
+        e0 = getNextTestEntry(dropbox, before);
+        e1 = getNextTestEntry(dropbox, e0.getTimeMillis());
+        e2 = getNextTestEntry(dropbox, e1.getTimeMillis());
+        e3 = getNextTestEntry(dropbox, e2.getTimeMillis());
+        assertTrue(null == getNextTestEntry(dropbox, e3.getTimeMillis()));
+
+        assertEquals("FUTURE0", e0.getText(80));
+        assertEquals("FUTURE1", e1.getText(80));
+        assertEquals("FUTURE2", e2.getText(80));
+        assertEquals(null, e3.getText(80));
+
+        assertEquals(before + 5000, e0.getTimeMillis());
+        assertEquals(before + 5001, e1.getTimeMillis());
+        assertEquals(before + 5002, e2.getTimeMillis());
+        assertEquals(before + 5003, e3.getTimeMillis());
+
+        e0.close();
+        e1.close();
+        e2.close();
+        e3.close();
+        dropbox.stop();
+    }
+
+    public void testIsTagEnabled() throws Exception {
+        IDropBox dropbox = IDropBox.Stub.asInterface(ServiceManager.getService("dropbox"));
+        long before = System.currentTimeMillis();
+        dropbox.addText("DropBoxTest", "TEST-ENABLED");
+        assertTrue(dropbox.isTagEnabled("DropBoxTest"));
+
+        Intent override = new Intent(Settings.Gservices.OVERRIDE_ACTION);
+        override.putExtra(Settings.Gservices.DROPBOX_TAG_PREFIX + "DropBoxTest", "disabled");
+        waitForBroadcast(override);
+
+        dropbox.addText("DropBoxTest", "TEST-DISABLED");
+        assertFalse(dropbox.isTagEnabled("DropBoxTest"));
+
+        override = new Intent(Settings.Gservices.OVERRIDE_ACTION);
+        override.putExtra(Settings.Gservices.DROPBOX_TAG_PREFIX + "DropBoxTest", "");
+        waitForBroadcast(override);
+
+        dropbox.addText("DropBoxTest", "TEST-ENABLED-AGAIN");
+        assertTrue(dropbox.isTagEnabled("DropBoxTest"));
+
+        DropBoxEntry e0 = getNextTestEntry(dropbox, before);
+        DropBoxEntry e1 = getNextTestEntry(dropbox, e0.getTimeMillis());
+        assertTrue(null == getNextTestEntry(dropbox, e1.getTimeMillis()));
+
+        assertEquals("TEST-ENABLED", e0.getText(80));
+        assertEquals("TEST-ENABLED-AGAIN", e1.getText(80));
+
+        e0.close();
+        e1.close();
+    }
+
+    public void testSizeLimits() throws Exception {
+        File dir = getEmptyDir("testSizeLimits");
+        int blockSize =  new StatFs(dir.getPath()).getBlockSize();
+
+        // Limit storage to 10 blocks
+        int kb = blockSize * 10 / 1024;
+        Intent override = new Intent(Settings.Gservices.OVERRIDE_ACTION);
+        override.putExtra(Settings.Gservices.DROPBOX_QUOTA_KB, Integer.toString(kb));
+        waitForBroadcast(override);
+
+        // Three tags using a total of 12 blocks:
+        // DropBoxTest0 [ ][ ]
+        // DropBoxTest1 [x][ ][    ][ ][xxx(20 blocks)xxx]
+        // DropBoxTest2 [xxxxxxxxxx][ ][ ]
+        //
+        // The blocks marked "x" will be removed due to storage restrictions.
+        // Use random fill (so it doesn't compress), subtract a little for gzip overhead
+
+        final int overhead = 64;
+        long before = System.currentTimeMillis();
+        DropBoxService dropbox = new DropBoxService(getContext(), dir);
+        addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead);
+        addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead);
+
+        addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead);
+        addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead);
+        addRandomEntry(dropbox, "DropBoxTest1", blockSize * 2 - overhead);
+        addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead);
+        addRandomEntry(dropbox, "DropBoxTest1", blockSize * 20 - overhead);
+
+        addRandomEntry(dropbox, "DropBoxTest2", blockSize * 4 - overhead);
+        addRandomEntry(dropbox, "DropBoxTest2", blockSize - overhead);
+        addRandomEntry(dropbox, "DropBoxTest2", blockSize - overhead);
+
+        DropBoxEntry e0 = getNextTestEntry(dropbox, before);
+        DropBoxEntry e1 = getNextTestEntry(dropbox, e0.getTimeMillis());
+        DropBoxEntry e2 = getNextTestEntry(dropbox, e1.getTimeMillis());
+        DropBoxEntry e3 = getNextTestEntry(dropbox, e2.getTimeMillis());
+        DropBoxEntry e4 = getNextTestEntry(dropbox, e3.getTimeMillis());
+        DropBoxEntry e5 = getNextTestEntry(dropbox, e4.getTimeMillis());
+        DropBoxEntry e6 = getNextTestEntry(dropbox, e5.getTimeMillis());
+        DropBoxEntry e7 = getNextTestEntry(dropbox, e6.getTimeMillis());
+        DropBoxEntry e8 = getNextTestEntry(dropbox, e7.getTimeMillis());
+        DropBoxEntry e9 = getNextTestEntry(dropbox, e8.getTimeMillis());
+        assertTrue(null == getNextTestEntry(dropbox, e9.getTimeMillis()));
+
+        assertEquals("DropBoxTest0", e0.getTag());
+        assertEquals("DropBoxTest0", e1.getTag());
+        assertEquals(blockSize - overhead, getEntrySize(e0));
+        assertEquals(blockSize - overhead, getEntrySize(e1));
+
+        assertEquals("DropBoxTest1", e2.getTag());
+        assertEquals("DropBoxTest1", e3.getTag());
+        assertEquals("DropBoxTest1", e4.getTag());
+        assertEquals("DropBoxTest1", e5.getTag());
+        assertEquals("DropBoxTest1", e6.getTag());
+        assertEquals(-1, getEntrySize(e2));  // Tombstone
+        assertEquals(blockSize - overhead, getEntrySize(e3));
+        assertEquals(blockSize * 2 - overhead, getEntrySize(e4));
+        assertEquals(blockSize - overhead, getEntrySize(e5));
+        assertEquals(-1, getEntrySize(e6));
+
+        assertEquals("DropBoxTest2", e7.getTag());
+        assertEquals("DropBoxTest2", e8.getTag());
+        assertEquals("DropBoxTest2", e9.getTag());
+        assertEquals(-1, getEntrySize(e7));  // Tombstone
+        assertEquals(blockSize - overhead, getEntrySize(e8));
+        assertEquals(blockSize - overhead, getEntrySize(e9));
+
+        e0.close();
+        e1.close();
+        e2.close();
+        e3.close();
+        e4.close();
+        e5.close();
+        e6.close();
+        e7.close();
+        e8.close();
+        e9.close();
+        dropbox.stop();
+    }
+
+    public void testAgeLimits() throws Exception {
+        File dir = getEmptyDir("testAgeLimits");
+        int blockSize = new StatFs(dir.getPath()).getBlockSize();
+
+        // Limit storage to 10 blocks with an expiration of 1 second
+        int kb = blockSize * 10 / 1024;
+        Intent override = new Intent(Settings.Gservices.OVERRIDE_ACTION);
+        override.putExtra(Settings.Gservices.DROPBOX_AGE_SECONDS, "1");
+        override.putExtra(Settings.Gservices.DROPBOX_QUOTA_KB, Integer.toString(kb));
+        waitForBroadcast(override);
+
+        // Write one normal entry and another so big that it is instantly tombstoned
+        long before = System.currentTimeMillis();
+        DropBoxService dropbox = new DropBoxService(getContext(), dir);
+        dropbox.addText("DropBoxTest", "TEST");
+        addRandomEntry(dropbox, "DropBoxTest", blockSize * 20);
+
+        // Verify that things are as expected
+        DropBoxEntry e0 = getNextTestEntry(dropbox, before);
+        DropBoxEntry e1 = getNextTestEntry(dropbox, e0.getTimeMillis());
+        assertTrue(null == getNextTestEntry(dropbox, e1.getTimeMillis()));
+
+        assertEquals("TEST", e0.getText(80));
+        assertEquals(null, e1.getText(80));
+        assertEquals(-1, getEntrySize(e1));
+
+        e0.close();
+        e1.close();
+
+        // Wait a second and write another entry -- old ones should be expunged
+        Thread.sleep(2000);
+        dropbox.addText("DropBoxTest", "TEST1");
+
+        e0 = getNextTestEntry(dropbox, before);
+        assertTrue(null == getNextTestEntry(dropbox, e0.getTimeMillis()));
+        assertEquals("TEST1", e0.getText(80));
+        e0.close();
+    }
+
+    public void testCreateDropBoxWithInvalidDirectory() throws Exception {
+        // If created with an invalid directory, the DropBox should suffer quietly
+        // and fail all operations (this is how it survives a full disk).
+        // Once the directory becomes possible to create, it will start working.
+
+        File dir = new File(getEmptyDir("testCreateDropBoxWith"), "InvalidDirectory");
+        new FileOutputStream(dir).close();  // Create an empty file
+        DropBoxService dropbox = new DropBoxService(getContext(), dir);
+
+        dropbox.addText("DropBoxTest", "should be ignored");
+        dropbox.addData("DropBoxTest", "should be ignored".getBytes(), 0);
+        assertTrue(null == getNextTestEntry(dropbox, 0));
+
+        dir.delete();  // Remove the file so a directory can be created
+        dropbox.addText("DropBoxTest", "TEST");
+        DropBoxEntry e = getNextTestEntry(dropbox, 0);
+        assertTrue(null == getNextTestEntry(dropbox, e.getTimeMillis()));
+        assertEquals("DropBoxTest", e.getTag());
+        assertEquals("TEST", e.getText(80));
+        e.close();
+        dropbox.stop();
+    }
+
+    private void addRandomEntry(IDropBox dropbox, String tag, int size) throws Exception {
+        byte[] bytes = new byte[size];
+        new Random(System.currentTimeMillis()).nextBytes(bytes);
+
+        File f = new File(getEmptyDir("addRandomEntry"), "random.dat");
+        FileOutputStream os = new FileOutputStream(f);
+        os.write(bytes);
+        os.close();
+
+        ParcelFileDescriptor fd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
+        dropbox.addFile(tag, fd, 0);
+        fd.close();
+    }
+
+    private int getEntrySize(DropBoxEntry e) throws Exception {
+        InputStream is = e.getInputStream();
+        if (is == null) return -1;
+        int length = 0;
+        while (is.read() != -1) length++;
+        return length;
+    }
+
+    private void waitForBroadcast(Intent intent) throws InterruptedException {
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            public synchronized void onReceive(Context context, Intent intent) { notify(); }
+        };
+
+        getContext().sendOrderedBroadcast(intent, null, receiver, null, 0, null, null);
+        synchronized (receiver) { receiver.wait(); }
+    }
+
+    private void recursiveDelete(File file) {
+        if (!file.delete() && file.isDirectory()) {
+            for (File f : file.listFiles()) recursiveDelete(f);
+            file.delete();
+        }
+    }
+
+    private File getEmptyDir(String name) {
+        File dir = getContext().getDir("DropBoxTest." + name, 0);
+        for (File f : dir.listFiles()) recursiveDelete(f);
+        assertTrue(dir.listFiles().length == 0);
+        return dir;
+    }
+
+    private DropBoxEntry getNextTestEntry(IDropBox dropbox, long millis) throws Exception {
+        for (;;) {
+            DropBoxEntry entry = dropbox.getNextEntry(millis);
+            if (entry == null || entry.getTag().startsWith("DropBoxTest")) return entry;
+            entry.close();
+            millis = entry.getTimeMillis();
+        }
+    }
+}
