diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 1ba7e79..663a031 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -16,16 +16,15 @@
 
 package com.android.server;
 
-import com.android.internal.os.AtomicFile;
-import com.android.internal.statusbar.StatusBarNotification;
-import com.android.internal.util.FastXmlSerializer;
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.INotificationManager;
 import android.app.ITransientNotification;
 import android.app.Notification;
-import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
@@ -39,8 +38,8 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.media.AudioManager;
-import android.net.NetworkPolicy;
-import android.net.NetworkTemplate;
+import android.media.IAudioService;
+import android.media.IRingtonePlayer;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Handler;
@@ -48,6 +47,7 @@
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.UserId;
 import android.os.Vibrator;
 import android.provider.Settings;
@@ -61,6 +61,14 @@
 import android.view.accessibility.AccessibilityManager;
 import android.widget.Toast;
 
+import com.android.internal.os.AtomicFile;
+import com.android.internal.statusbar.StatusBarNotification;
+import com.android.internal.util.FastXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -74,18 +82,6 @@
 
 import libcore.io.IoUtils;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import static android.net.NetworkPolicyManager.POLICY_NONE;
-import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeBooleanAttribute;
-import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeIntAttribute;
-import static com.android.server.net.NetworkPolicyManagerService.XmlUtils.writeLongAttribute;
-import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
-import static org.xmlpull.v1.XmlPullParser.END_TAG;
-import static org.xmlpull.v1.XmlPullParser.START_TAG;
-
 
 /** {@hide} */
 public class NotificationManagerService extends INotificationManager.Stub
@@ -126,12 +122,13 @@
     private int mDefaultNotificationLedOn;
     private int mDefaultNotificationLedOff;
 
-    private NotificationRecord mSoundNotification;
-    private NotificationPlayer mSound;
     private boolean mSystemReady;
     private int mDisabledNotifications;
 
+    private NotificationRecord mSoundNotification;
     private NotificationRecord mVibrateNotification;
+
+    private IAudioService mAudioService;
     private Vibrator mVibrator;
 
     // for enabling and disabling notification pulse behavior
@@ -409,17 +406,19 @@
                     // cancel whatever's going on
                     long identity = Binder.clearCallingIdentity();
                     try {
-                        mSound.stop();
-                    }
-                    finally {
+                        final IRingtonePlayer player = mAudioService.getRingtonePlayer();
+                        if (player != null) {
+                            player.stopAsync();
+                        }
+                    } catch (RemoteException e) {
+                    } finally {
                         Binder.restoreCallingIdentity(identity);
                     }
 
                     identity = Binder.clearCallingIdentity();
                     try {
                         mVibrator.cancel();
-                    }
-                    finally {
+                    } finally {
                         Binder.restoreCallingIdentity(identity);
                     }
                 }
@@ -445,11 +444,15 @@
             synchronized (mNotificationList) {
                 // sound
                 mSoundNotification = null;
+
                 long identity = Binder.clearCallingIdentity();
                 try {
-                    mSound.stop();
-                }
-                finally {
+                    final IRingtonePlayer player = mAudioService.getRingtonePlayer();
+                    if (player != null) {
+                        player.stopAsync();
+                    }
+                } catch (RemoteException e) {
+                } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
 
@@ -458,8 +461,7 @@
                 identity = Binder.clearCallingIdentity();
                 try {
                     mVibrator.cancel();
-                }
-                finally {
+                } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
 
@@ -570,8 +572,6 @@
         mContext = context;
         mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
         mAm = ActivityManagerNative.getDefault();
-        mSound = new NotificationPlayer(TAG);
-        mSound.setUsesWakeLock(context);
         mToastQueue = new ArrayList<ToastRecord>();
         mHandler = new WorkerHandler();
 
@@ -622,6 +622,9 @@
     }
 
     void systemReady() {
+        mAudioService = IAudioService.Stub.asInterface(
+                ServiceManager.getService(Context.AUDIO_SERVICE));
+
         // no beeping until we're basically done booting
         mSystemReady = true;
     }
@@ -1026,11 +1029,14 @@
                     // do not play notifications if stream volume is 0
                     // (typically because ringer mode is silent).
                     if (audioManager.getStreamVolume(audioStreamType) != 0) {
-                        long identity = Binder.clearCallingIdentity();
+                        final long identity = Binder.clearCallingIdentity();
                         try {
-                            mSound.play(mContext, uri, looping, audioStreamType);
-                        }
-                        finally {
+                            final IRingtonePlayer player = mAudioService.getRingtonePlayer();
+                            if (player != null) {
+                                player.playAsync(uri, looping, audioStreamType);
+                            }
+                        } catch (RemoteException e) {
+                        } finally {
                             Binder.restoreCallingIdentity(identity);
                         }
                     }
@@ -1121,11 +1127,14 @@
         // sound
         if (mSoundNotification == r) {
             mSoundNotification = null;
-            long identity = Binder.clearCallingIdentity();
+            final long identity = Binder.clearCallingIdentity();
             try {
-                mSound.stop();
-            }
-            finally {
+                final IRingtonePlayer player = mAudioService.getRingtonePlayer();
+                if (player != null) {
+                    player.stopAsync();
+                }
+            } catch (RemoteException e) {
+            } finally {
                 Binder.restoreCallingIdentity(identity);
             }
         }
@@ -1386,7 +1395,6 @@
             }
 
             pw.println("  mSoundNotification=" + mSoundNotification);
-            pw.println("  mSound=" + mSound);
             pw.println("  mVibrateNotification=" + mVibrateNotification);
             pw.println("  mDisabledNotifications=0x" + Integer.toHexString(mDisabledNotifications));
             pw.println("  mSystemReady=" + mSystemReady);
diff --git a/services/java/com/android/server/NotificationPlayer.java b/services/java/com/android/server/NotificationPlayer.java
deleted file mode 100644
index 52d2381..0000000
--- a/services/java/com/android/server/NotificationPlayer.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * 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 com.android.server;
-
-import android.content.Context;
-import android.media.AudioManager;
-import android.media.MediaPlayer;
-import android.media.MediaPlayer.OnCompletionListener;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.io.IOException;
-import java.lang.IllegalStateException;
-import java.lang.Thread;
-import java.util.LinkedList;
-
-/**
- * @hide
- * This class is provides the same interface and functionality as android.media.AsyncPlayer
- * with the following differences: 
- * - whenever audio is played, audio focus is requested,
- * - whenever audio playback is stopped or the playback completed, audio focus is abandoned.
- */
-public class NotificationPlayer implements OnCompletionListener {
-    private static final int PLAY = 1;
-    private static final int STOP = 2;
-    private static final boolean mDebug = false;
-
-    private static final class Command {
-        int code;
-        Context context;
-        Uri uri;
-        boolean looping;
-        int stream;
-        long requestTime;
-
-        public String toString() {
-            return "{ code=" + code + " looping=" + looping + " stream=" + stream
-                    + " uri=" + uri + " }";
-        }
-    }
-
-    private LinkedList<Command> mCmdQueue = new LinkedList();
-
-    private Looper mLooper;
-
-    /*
-     * Besides the use of audio focus, the only implementation difference between AsyncPlayer and
-     * NotificationPlayer resides in the creation of the MediaPlayer. For the completion callback,
-     * OnCompletionListener, to be called at the end of the playback, the MediaPlayer needs to
-     * be created with a looper running so its event handler is not null.
-     */
-    private final class CreationAndCompletionThread extends Thread {
-        public Command mCmd;
-        public CreationAndCompletionThread(Command cmd) {
-            super();
-            mCmd = cmd;
-        }
-
-        public void run() {
-            Looper.prepare();
-            mLooper = Looper.myLooper();
-            synchronized(this) {
-                AudioManager audioManager =
-                    (AudioManager) mCmd.context.getSystemService(Context.AUDIO_SERVICE);
-                try {
-                    MediaPlayer player = new MediaPlayer();
-                    player.setAudioStreamType(mCmd.stream);
-                    player.setDataSource(mCmd.context, mCmd.uri);
-                    player.setLooping(mCmd.looping);
-                    player.prepare();
-                    if ((mCmd.uri != null) && (mCmd.uri.getEncodedPath() != null)
-                            && (mCmd.uri.getEncodedPath().length() > 0)) {
-                        if (mCmd.looping) {
-                            audioManager.requestAudioFocus(null, mCmd.stream,
-                                    AudioManager.AUDIOFOCUS_GAIN);
-                        } else {
-                            audioManager.requestAudioFocus(null, mCmd.stream,
-                                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
-                        }
-                    }
-                    player.setOnCompletionListener(NotificationPlayer.this);
-                    player.start();
-                    if (mPlayer != null) {
-                        mPlayer.release();
-                    }
-                    mPlayer = player;
-                }
-                catch (Exception e) {
-                    Log.w(mTag, "error loading sound for " + mCmd.uri, e);
-                }
-                mAudioManager = audioManager;
-                this.notify();
-            }
-            Looper.loop();
-        }
-    };
-
-    private void startSound(Command cmd) {
-        // Preparing can be slow, so if there is something else
-        // is playing, let it continue until we're done, so there
-        // is less of a glitch.
-        try {
-            if (mDebug) Log.d(mTag, "Starting playback");
-            //-----------------------------------
-            // This is were we deviate from the AsyncPlayer implementation and create the
-            // MediaPlayer in a new thread with which we're synchronized
-            synchronized(mCompletionHandlingLock) {
-                // if another sound was already playing, it doesn't matter we won't get notified
-                // of the completion, since only the completion notification of the last sound
-                // matters
-                if((mLooper != null)
-                        && (mLooper.getThread().getState() != Thread.State.TERMINATED)) {
-                    mLooper.quit();
-                }
-                mCompletionThread = new CreationAndCompletionThread(cmd);
-                synchronized(mCompletionThread) {
-                    mCompletionThread.start();
-                    mCompletionThread.wait();
-                }
-            }
-            //-----------------------------------
-
-            long delay = SystemClock.uptimeMillis() - cmd.requestTime;
-            if (delay > 1000) {
-                Log.w(mTag, "Notification sound delayed by " + delay + "msecs");
-            }
-        }
-        catch (Exception e) {
-            Log.w(mTag, "error loading sound for " + cmd.uri, e);
-        }
-    }
-
-    private final class CmdThread extends java.lang.Thread {
-        CmdThread() {
-            super("NotificationPlayer-" + mTag);
-        }
-
-        public void run() {
-            while (true) {
-                Command cmd = null;
-
-                synchronized (mCmdQueue) {
-                    if (mDebug) Log.d(mTag, "RemoveFirst");
-                    cmd = mCmdQueue.removeFirst();
-                }
-
-                switch (cmd.code) {
-                case PLAY:
-                    if (mDebug) Log.d(mTag, "PLAY");
-                    startSound(cmd);
-                    break;
-                case STOP:
-                    if (mDebug) Log.d(mTag, "STOP");
-                    if (mPlayer != null) {
-                        long delay = SystemClock.uptimeMillis() - cmd.requestTime;
-                        if (delay > 1000) {
-                            Log.w(mTag, "Notification stop delayed by " + delay + "msecs");
-                        }
-                        mPlayer.stop();
-                        mPlayer.release();
-                        mPlayer = null;
-                        mAudioManager.abandonAudioFocus(null);
-                        mAudioManager = null;
-                        if((mLooper != null)
-                                && (mLooper.getThread().getState() != Thread.State.TERMINATED)) {
-                            mLooper.quit();
-                        }
-                    } else {
-                        Log.w(mTag, "STOP command without a player");
-                    }
-                    break;
-                }
-
-                synchronized (mCmdQueue) {
-                    if (mCmdQueue.size() == 0) {
-                        // nothing left to do, quit
-                        // doing this check after we're done prevents the case where they
-                        // added it during the operation from spawning two threads and
-                        // trying to do them in parallel.
-                        mThread = null;
-                        releaseWakeLock();
-                        return;
-                    }
-                }
-            }
-        }
-    }
-
-    public void onCompletion(MediaPlayer mp) {
-        if (mAudioManager != null) {
-            mAudioManager.abandonAudioFocus(null);
-        }
-        // if there are no more sounds to play, end the Looper to listen for media completion
-        synchronized (mCmdQueue) {
-            if (mCmdQueue.size() == 0) {
-                synchronized(mCompletionHandlingLock) {
-                    if(mLooper != null) {
-                        mLooper.quit();
-                    }
-                    mCompletionThread = null;
-                }
-            }
-        }
-    }
-
-    private String mTag;
-    private CmdThread mThread;
-    private CreationAndCompletionThread mCompletionThread;
-    private final Object mCompletionHandlingLock = new Object();
-    private MediaPlayer mPlayer;
-    private PowerManager.WakeLock mWakeLock;
-    private AudioManager mAudioManager;
-
-    // The current state according to the caller.  Reality lags behind
-    // because of the asynchronous nature of this class.
-    private int mState = STOP;
-
-    /**
-     * Construct a NotificationPlayer object.
-     *
-     * @param tag a string to use for debugging
-     */
-    public NotificationPlayer(String tag) {
-        if (tag != null) {
-            mTag = tag;
-        } else {
-            mTag = "NotificationPlayer";
-        }
-    }
-
-    /**
-     * Start playing the sound.  It will actually start playing at some
-     * point in the future.  There are no guarantees about latency here.
-     * Calling this before another audio file is done playing will stop
-     * that one and start the new one.
-     *
-     * @param context Your application's context.
-     * @param uri The URI to play.  (see {@link MediaPlayer#setDataSource(Context, Uri)})
-     * @param looping Whether the audio should loop forever.
-     *          (see {@link MediaPlayer#setLooping(boolean)})
-     * @param stream the AudioStream to use.
-     *          (see {@link MediaPlayer#setAudioStreamType(int)})
-     */
-    public void play(Context context, Uri uri, boolean looping, int stream) {
-        Command cmd = new Command();
-        cmd.requestTime = SystemClock.uptimeMillis();
-        cmd.code = PLAY;
-        cmd.context = context;
-        cmd.uri = uri;
-        cmd.looping = looping;
-        cmd.stream = stream;
-        synchronized (mCmdQueue) {
-            enqueueLocked(cmd);
-            mState = PLAY;
-        }
-    }
-
-    /**
-     * Stop a previously played sound.  It can't be played again or unpaused
-     * at this point.  Calling this multiple times has no ill effects.
-     */
-    public void stop() {
-        synchronized (mCmdQueue) {
-            // This check allows stop to be called multiple times without starting
-            // a thread that ends up doing nothing.
-            if (mState != STOP) {
-                Command cmd = new Command();
-                cmd.requestTime = SystemClock.uptimeMillis();
-                cmd.code = STOP;
-                enqueueLocked(cmd);
-                mState = STOP;
-            }
-        }
-    }
-
-    private void enqueueLocked(Command cmd) {
-        mCmdQueue.add(cmd);
-        if (mThread == null) {
-            acquireWakeLock();
-            mThread = new CmdThread();
-            mThread.start();
-        }
-    }
-
-    /**
-     * We want to hold a wake lock while we do the prepare and play.  The stop probably is
-     * optional, but it won't hurt to have it too.  The problem is that if you start a sound
-     * while you're holding a wake lock (e.g. an alarm starting a notification), you want the
-     * sound to play, but if the CPU turns off before mThread gets to work, it won't.  The
-     * simplest way to deal with this is to make it so there is a wake lock held while the
-     * thread is starting or running.  You're going to need the WAKE_LOCK permission if you're
-     * going to call this.
-     *
-     * This must be called before the first time play is called.
-     *
-     * @hide
-     */
-    public void setUsesWakeLock(Context context) {
-        if (mWakeLock != null || mThread != null) {
-            // if either of these has happened, we've already played something.
-            // and our releases will be out of sync.
-            throw new RuntimeException("assertion failed mWakeLock=" + mWakeLock
-                    + " mThread=" + mThread);
-        }
-        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);
-    }
-
-    private void acquireWakeLock() {
-        if (mWakeLock != null) {
-            mWakeLock.acquire();
-        }
-    }
-
-    private void releaseWakeLock() {
-        if (mWakeLock != null) {
-            mWakeLock.release();
-        }
-    }
-}
-
