diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
new file mode 100644
index 0000000..333a450
--- /dev/null
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -0,0 +1,341 @@
+/*
+ * 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 com.android.providers.settings;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemProperties;
+import android.provider.DrmStore;
+import android.provider.MediaStore;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.FileNotFoundException;
+
+public class SettingsProvider extends ContentProvider {
+    private static final String TAG = "SettingsProvider";
+    private static final boolean LOCAL_LOGV = false;
+
+    private static final String TABLE_FAVORITES = "favorites";
+    private static final String TABLE_OLD_FAVORITES = "old_favorites";
+
+    private DatabaseHelper mOpenHelper;
+
+    /**
+     * Decode a content URL into the table, projection, and arguments
+     * used to access the corresponding database rows.
+     */
+    private static class SqlArguments {
+        public String table;
+        public final String where;
+        public final String[] args;
+
+        /** Operate on existing rows. */
+        SqlArguments(Uri url, String where, String[] args) {
+            if (url.getPathSegments().size() == 1) {
+                this.table = url.getPathSegments().get(0);
+                this.where = where;
+                this.args = args;
+            } else if (url.getPathSegments().size() != 2) {
+                throw new IllegalArgumentException("Invalid URI: " + url);
+            } else if (!TextUtils.isEmpty(where)) {
+                throw new UnsupportedOperationException("WHERE clause not supported: " + url);
+            } else {
+                this.table = url.getPathSegments().get(0);
+                if ("gservices".equals(this.table) || "system".equals(this.table)
+                        || "secure".equals(this.table)) {
+                    this.where = Settings.NameValueTable.NAME + "=?";
+                    this.args = new String[] { url.getPathSegments().get(1) };
+                } else {
+                    this.where = "_id=" + ContentUris.parseId(url);
+                    this.args = null;
+                }
+            }
+        }
+
+        /** Insert new rows (no where clause allowed). */
+        SqlArguments(Uri url) {
+            if (url.getPathSegments().size() == 1) {
+                this.table = url.getPathSegments().get(0);
+                this.where = null;
+                this.args = null;
+            } else {
+                throw new IllegalArgumentException("Invalid URI: " + url);
+            }
+        }
+    }
+
+    /**
+     * Get the content URI of a row added to a table.
+     * @param tableUri of the entire table
+     * @param values found in the row
+     * @param rowId of the row
+     * @return the content URI for this particular row
+     */
+    private Uri getUriFor(Uri tableUri, ContentValues values, long rowId) {
+        if (tableUri.getPathSegments().size() != 1) {
+            throw new IllegalArgumentException("Invalid URI: " + tableUri);
+        }
+        String table = tableUri.getPathSegments().get(0);
+        if ("gservices".equals(table) || "system".equals(table)
+                || "secure".equals(table)) {
+            String name = values.getAsString(Settings.NameValueTable.NAME);
+            return Uri.withAppendedPath(tableUri, name);
+        } else {
+            return ContentUris.withAppendedId(tableUri, rowId);
+        }
+    }
+
+    /**
+     * Send a notification when a particular content URI changes.
+     * Modify the system property used to communicate the version of
+     * this table, for tables which have such a property.  (The Settings
+     * contract class uses these to provide client-side caches.)
+     * @param uri to send notifications for
+     */
+    private void sendNotify(Uri uri) {
+        // Update the system property *first*, so if someone is listening for
+        // a notification and then using the contract class to get their data,
+        // the system property will be updated and they'll get the new data.
+
+        String property = null, table = uri.getPathSegments().get(0);
+        if (table.equals("system")) {
+            property = Settings.System.SYS_PROP_SETTING_VERSION;
+        } else if (table.equals("secure")) {
+            property = Settings.Secure.SYS_PROP_SETTING_VERSION;
+        } else if (table.equals("gservices")) {
+            property = Settings.Gservices.SYS_PROP_SETTING_VERSION;
+        }
+
+        if (property != null) {
+            long version = SystemProperties.getLong(property, 0) + 1;
+            if (LOCAL_LOGV) Log.v(TAG, "property: " + property + "=" + version);
+            SystemProperties.set(property, Long.toString(version));
+        }
+
+        // Now send the notification through the content framework.
+
+        String notify = uri.getQueryParameter("notify");
+        if (notify == null || "true".equals(notify)) {
+            getContext().getContentResolver().notifyChange(uri, null);
+            if (LOCAL_LOGV) Log.v(TAG, "notifying: " + uri);
+        } else {
+            if (LOCAL_LOGV) Log.v(TAG, "notification suppressed: " + uri);
+        }
+    }
+
+    /**
+     * Make sure the caller has permission to write this data.
+     * @param args supplied by the caller
+     * @throws SecurityException if the caller is forbidden to write.
+     */
+    private void checkWritePermissions(SqlArguments args) {
+        if ("secure".equals(args.table) &&
+                getContext().checkCallingOrSelfPermission(
+                        android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
+                    PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("Cannot write secure settings table");
+        
+        // TODO: Move gservices into its own provider so we don't need this nonsense.
+        } else if ("gservices".equals(args.table) &&
+            getContext().checkCallingOrSelfPermission(
+                    android.Manifest.permission.WRITE_GSERVICES) !=
+                PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Cannot write gservices table");
+        }
+    }
+
+    @Override
+    public boolean onCreate() {
+        mOpenHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri url, String[] select, String where, String[] whereArgs, String sort) {
+        SqlArguments args = new SqlArguments(url, where, whereArgs);
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+
+        // The favorites table was moved from this provider to a provider inside Home
+        // Home still need to query this table to upgrade from pre-cupcake builds
+        // However, a cupcake+ build with no data does not contain this table which will
+        // cause an exception in the SQL stack. The following line is a special case to
+        // let the caller of the query have a chance to recover and avoid the exception
+        if (TABLE_FAVORITES.equals(args.table)) {
+            return null;
+        } else if (TABLE_OLD_FAVORITES.equals(args.table)) {
+            args.table = TABLE_FAVORITES;
+            Cursor cursor = db.rawQuery("PRAGMA table_info(favorites);", null);
+            if (cursor != null) {
+                boolean exists = cursor.getCount() > 0;
+                cursor.close();
+                if (!exists) return null;
+            } else {
+                return null;
+            }
+        }
+
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        qb.setTables(args.table);
+
+        Cursor ret = qb.query(db, select, args.where, args.args, null, null, sort);
+        ret.setNotificationUri(getContext().getContentResolver(), url);
+        return ret;
+    }
+
+    @Override
+    public String getType(Uri url) {
+        // If SqlArguments supplies a where clause, then it must be an item
+        // (because we aren't supplying our own where clause).
+        SqlArguments args = new SqlArguments(url, null, null);
+        if (TextUtils.isEmpty(args.where)) {
+            return "vnd.android.cursor.dir/" + args.table;
+        } else {
+            return "vnd.android.cursor.item/" + args.table;
+        }
+    }
+
+    @Override
+    public int bulkInsert(Uri uri, ContentValues[] values) {
+        SqlArguments args = new SqlArguments(uri);
+        if (TABLE_FAVORITES.equals(args.table)) {
+            return 0;
+        }
+        checkWritePermissions(args);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            int numValues = values.length;
+            for (int i = 0; i < numValues; i++) {
+                if (db.insert(args.table, null, values[i]) < 0) return 0;
+                if (LOCAL_LOGV) Log.v(TAG, args.table + " <- " + values[i]);
+            }
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+
+        sendNotify(uri);
+        return values.length;
+    }
+
+    @Override
+    public Uri insert(Uri url, ContentValues initialValues) {
+        SqlArguments args = new SqlArguments(url);
+        if (TABLE_FAVORITES.equals(args.table)) {
+            return null;
+        }
+        checkWritePermissions(args);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        final long rowId = db.insert(args.table, null, initialValues);
+        if (rowId <= 0) return null;
+
+        if (LOCAL_LOGV) Log.v(TAG, args.table + " <- " + initialValues);
+        url = getUriFor(url, initialValues, rowId);
+        sendNotify(url);
+        return url;
+    }
+
+    @Override
+    public int delete(Uri url, String where, String[] whereArgs) {
+        SqlArguments args = new SqlArguments(url, where, whereArgs);
+        if (TABLE_FAVORITES.equals(args.table)) {
+            return 0;
+        } else if (TABLE_OLD_FAVORITES.equals(args.table)) {
+            args.table = TABLE_FAVORITES;
+        }
+        checkWritePermissions(args);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count = db.delete(args.table, args.where, args.args);
+        if (count > 0) sendNotify(url);
+        if (LOCAL_LOGV) Log.v(TAG, args.table + ": " + count + " row(s) deleted");
+        return count;
+    }
+
+    @Override
+    public int update(Uri url, ContentValues initialValues, String where, String[] whereArgs) {
+        SqlArguments args = new SqlArguments(url, where, whereArgs);
+        if (TABLE_FAVORITES.equals(args.table)) {
+            return 0;
+        }
+        checkWritePermissions(args);
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count = db.update(args.table, initialValues, args.where, args.args);
+        if (count > 0) sendNotify(url);
+        if (LOCAL_LOGV) Log.v(TAG, args.table + ": " + count + " row(s) <- " + initialValues);
+        return count;
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+
+        /*
+         * When a client attempts to openFile the default ringtone or
+         * notification setting Uri, we will proxy the call to the current
+         * default ringtone's Uri (if it is in the DRM or media provider).
+         */ 
+        int ringtoneType = RingtoneManager.getDefaultType(uri);
+        // Above call returns -1 if the Uri doesn't match a default type
+        if (ringtoneType != -1) {
+            Context context = getContext();
+            
+            // Get the current value for the default sound
+            Uri soundUri = RingtoneManager.getActualDefaultRingtoneUri(context, ringtoneType);
+            if (soundUri == null) {
+                // Fallback on any valid ringtone Uri
+                soundUri = RingtoneManager.getValidRingtoneUri(context);
+            }
+
+            if (soundUri != null) { 
+                // Only proxy the openFile call to drm or media providers
+                String authority = soundUri.getAuthority();
+                boolean isDrmAuthority = authority.equals(DrmStore.AUTHORITY);
+                if (isDrmAuthority || authority.equals(MediaStore.AUTHORITY)) {
+
+                    if (isDrmAuthority) {
+                        try {
+                            // Check DRM access permission here, since once we
+                            // do the below call the DRM will be checking our
+                            // permission, not our caller's permission
+                            DrmStore.enforceAccessDrmPermission(context);
+                        } catch (SecurityException e) {
+                            throw new FileNotFoundException(e.getMessage());
+                        }
+                    }
+                    
+                    return context.getContentResolver().openFileDescriptor(soundUri, mode);
+                }
+            }
+        }
+
+        return super.openFile(uri, mode);
+    }
+}
