diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2c6bafc..152ff30 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -502,7 +502,6 @@
     private volatile IRingtonePlayer mRingtonePlayer;
 
     private int mDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
-    private int mDeviceRotation = Surface.ROTATION_0;
 
     // Request to override default use of A2DP for media.
     private boolean mBluetoothA2dpEnabled;
@@ -546,8 +545,6 @@
     // If absolute volume is supported in AVRCP device
     private boolean mAvrcpAbsVolSupported = false;
 
-    private AudioOrientationEventListener mOrientationListener;
-
     private static Long mLastDeviceConnectMsgTime = new Long(0);
 
     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
@@ -670,15 +667,7 @@
         }
         mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
         if (mMonitorRotation) {
-            mDeviceRotation = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE))
-                    .getDefaultDisplay().getRotation();
-            Log.v(TAG, "monitoring device rotation, initial=" + mDeviceRotation);
-
-            mOrientationListener = new AudioOrientationEventListener(mContext);
-            mOrientationListener.enable();
-
-            // initialize rotation in AudioSystem
-            setRotationForAudioSystem();
+            RotationHelper.init(mContext, mAudioHandler);
         }
 
         context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
@@ -808,7 +797,7 @@
             setOrientationForAudioSystem();
         }
         if (mMonitorRotation) {
-            setRotationForAudioSystem();
+            RotationHelper.updateOrientation();
         }
 
         synchronized (mBluetoothA2dpEnabledLock) {
@@ -1061,25 +1050,6 @@
         return (index * mStreamStates[dstStream].getMaxIndex() + mStreamStates[srcStream].getMaxIndex() / 2) / mStreamStates[srcStream].getMaxIndex();
     }
 
-    private class AudioOrientationEventListener
-            extends OrientationEventListener {
-        public AudioOrientationEventListener(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void onOrientationChanged(int orientation) {
-            //Even though we're responding to phone orientation events,
-            //use display rotation so audio stays in sync with video/dialogs
-            int newRotation = ((WindowManager) mContext.getSystemService(
-                    Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
-            if (newRotation != mDeviceRotation) {
-                mDeviceRotation = newRotation;
-                setRotationForAudioSystem();
-            }
-        }
-    }
-
     ///////////////////////////////////////////////////////////////////////////
     // IPC methods
     ///////////////////////////////////////////////////////////////////////////
@@ -5069,14 +5039,13 @@
                 }
             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
                 if (mMonitorRotation) {
-                    mOrientationListener.onOrientationChanged(0); //argument is ignored anyway
-                    mOrientationListener.enable();
+                    RotationHelper.enable();
                 }
                 AudioSystem.setParameters("screen_state=on");
             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                 if (mMonitorRotation) {
                     //reduce wakeups (save current) by only listening when display is on
-                    mOrientationListener.disable();
+                    RotationHelper.disable();
                 }
                 AudioSystem.setParameters("screen_state=off");
             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
@@ -5321,6 +5290,7 @@
         }
     }
 
+    //TODO move to an external "orientation helper" class
     private void setOrientationForAudioSystem() {
         switch (mDeviceOrientation) {
             case Configuration.ORIENTATION_LANDSCAPE:
@@ -5344,26 +5314,6 @@
         }
     }
 
-    private void setRotationForAudioSystem() {
-        switch (mDeviceRotation) {
-            case Surface.ROTATION_0:
-                AudioSystem.setParameters("rotation=0");
-                break;
-            case Surface.ROTATION_90:
-                AudioSystem.setParameters("rotation=90");
-                break;
-            case Surface.ROTATION_180:
-                AudioSystem.setParameters("rotation=180");
-                break;
-            case Surface.ROTATION_270:
-                AudioSystem.setParameters("rotation=270");
-                break;
-            default:
-                Log.e(TAG, "Unknown device rotation");
-        }
-    }
-
-
     // Handles request to override default use of A2DP for media.
     // Must be called synchronized on mConnectedDevices
     public void setBluetoothA2dpOnInt(boolean on) {
diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java
new file mode 100644
index 0000000..f03e6c7
--- /dev/null
+++ b/services/core/java/com/android/server/audio/RotationHelper.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2015 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.audio;
+
+import android.content.Context;
+import android.media.AudioSystem;
+import android.os.Handler;
+import android.util.Log;
+import android.view.OrientationEventListener;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import com.android.server.policy.WindowOrientationListener;
+
+/**
+ * Class to handle device rotation events for AudioService, and forward device rotation
+ * to the audio HALs through AudioSystem.
+ *
+ * The role of this class is to monitor device orientation changes, and upon rotation,
+ * verify the UI orientation. In case of a change, send the new orientation, in increments
+ * of 90deg, through AudioSystem.
+ *
+ * Note that even though we're responding to device orientation events, we always
+ * query the display rotation so audio stays in sync with video/dialogs. This is
+ * done with .getDefaultDisplay().getRotation() from WINDOW_SERVICE.
+ */
+class RotationHelper {
+
+    private static final String TAG = "AudioService.RotationHelper";
+
+    private static AudioOrientationListener sOrientationListener;
+    private static AudioWindowOrientationListener sWindowOrientationListener;
+
+    private static final Object sRotationLock = new Object();
+    private static int sDeviceRotation = Surface.ROTATION_0; // R/W synchronized on sRotationLock
+
+    private static Context sContext;
+
+    /**
+     * post conditions:
+     * - (sWindowOrientationListener != null) xor (sOrientationListener != null)
+     * - sWindowOrientationListener xor sOrientationListener is enabled
+     * - sContext != null
+     */
+    static void init(Context context, Handler handler) {
+        if (context == null) {
+            throw new IllegalArgumentException("Invalid null context");
+        }
+        sContext = context;
+        sWindowOrientationListener = new AudioWindowOrientationListener(context, handler);
+        sWindowOrientationListener.enable();
+        if (!sWindowOrientationListener.canDetectOrientation()) {
+            // cannot use com.android.server.policy.WindowOrientationListener, revert to public
+            // orientation API
+            Log.i(TAG, "Not using WindowOrientationListener, reverting to OrientationListener");
+            sWindowOrientationListener.disable();
+            sWindowOrientationListener = null;
+            sOrientationListener = new AudioOrientationListener(context);
+            sOrientationListener.enable();
+        }
+    }
+
+    static void enable() {
+        if (sWindowOrientationListener != null) {
+            sWindowOrientationListener.enable();
+        } else {
+            sOrientationListener.enable();
+        }
+        updateOrientation();
+    }
+
+    static void disable() {
+        if (sWindowOrientationListener != null) {
+            sWindowOrientationListener.disable();
+        } else {
+            sOrientationListener.disable();
+        }
+    }
+
+    /**
+     * Query current display rotation and publish the change if any.
+     */
+    static void updateOrientation() {
+        // Even though we're responding to device orientation events,
+        // use display rotation so audio stays in sync with video/dialogs
+        int newRotation = ((WindowManager) sContext.getSystemService(
+                Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
+        synchronized(sRotationLock) {
+            if (newRotation != sDeviceRotation) {
+                sDeviceRotation = newRotation;
+                publishRotation(sDeviceRotation);
+            }
+        }
+    }
+
+    private static void publishRotation(int rotation) {
+        Log.v(TAG, "publishing device rotation =" + rotation + " (x90deg)");
+        switch (rotation) {
+            case Surface.ROTATION_0:
+                AudioSystem.setParameters("rotation=0");
+                break;
+            case Surface.ROTATION_90:
+                AudioSystem.setParameters("rotation=90");
+                break;
+            case Surface.ROTATION_180:
+                AudioSystem.setParameters("rotation=180");
+                break;
+            case Surface.ROTATION_270:
+                AudioSystem.setParameters("rotation=270");
+                break;
+            default:
+                Log.e(TAG, "Unknown device rotation");
+        }
+    }
+
+    /**
+     * Uses android.view.OrientationEventListener
+     */
+    final static class AudioOrientationListener extends OrientationEventListener {
+        AudioOrientationListener(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void onOrientationChanged(int orientation) {
+            updateOrientation();
+        }
+    }
+
+    /**
+     * Uses com.android.server.policy.WindowOrientationListener
+     */
+    final static class AudioWindowOrientationListener extends WindowOrientationListener {
+        private static RotationCheckThread sRotationCheckThread;
+
+        AudioWindowOrientationListener(Context context, Handler handler) {
+            super(context, handler);
+        }
+
+        public void onProposedRotationChanged(int rotation) {
+            updateOrientation();
+            if (sRotationCheckThread != null) {
+                sRotationCheckThread.endCheck();
+            }
+            sRotationCheckThread = new RotationCheckThread();
+            sRotationCheckThread.beginCheck();
+        }
+    }
+
+    /**
+     * When com.android.server.policy.WindowOrientationListener report an orientation change,
+     * the UI may not have rotated yet. This thread polls with gradually increasing delays
+     * the new orientation.
+     */
+    final static class RotationCheckThread extends Thread {
+        // how long to wait between each rotation check
+        private final int[] WAIT_TIMES_MS = { 10, 20, 50, 100, 100, 200, 200, 500 };
+        private int mWaitCounter;
+        private final Object mCounterLock = new Object();
+
+        RotationCheckThread() {
+            super("RotationCheck");
+        }
+
+        void beginCheck() {
+            synchronized(mCounterLock) {
+                mWaitCounter = 0;
+            }
+            try {
+                start();
+            } catch (IllegalStateException e) { }
+        }
+
+        void endCheck() {
+            synchronized(mCounterLock) {
+                mWaitCounter = WAIT_TIMES_MS.length;
+            }
+        }
+
+        public void run() {
+            int newRotation;
+            while (mWaitCounter < WAIT_TIMES_MS.length) {
+                updateOrientation();
+                int waitTimeMs;
+                synchronized(mCounterLock) {
+                    waitTimeMs = WAIT_TIMES_MS[mWaitCounter];
+                    mWaitCounter++;
+                }
+                try {
+                    sleep(waitTimeMs);
+                } catch (InterruptedException e) { }
+            }
+        }
+    }
+}
\ No newline at end of file
