Merge "Add the checking for the camcorder profile." into klp-dev
diff --git a/api/current.txt b/api/current.txt
index 118737f..42ba6b8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12857,6 +12857,7 @@
     field public static final int CAMCORDER = 5; // 0x5
     field public static final int DEFAULT = 0; // 0x0
     field public static final int MIC = 1; // 0x1
+    field public static final int REMOTE_SUBMIX = 8; // 0x8
     field public static final int VOICE_CALL = 4; // 0x4
     field public static final int VOICE_COMMUNICATION = 7; // 0x7
     field public static final int VOICE_DOWNLINK = 3; // 0x3
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index d6c5e4f..7d99464 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -41,11 +41,15 @@
 
 static int check_AudioSystem_Command(status_t status)
 {
-    if (status == NO_ERROR) {
+    switch (status) {
+    case DEAD_OBJECT:
+        return kAudioStatusMediaServerDied;
+    case NO_ERROR:
         return kAudioStatusOk;
-    } else {
-        return kAudioStatusError;
+    default:
+        break;
     }
+    return kAudioStatusError;
 }
 
 static int
@@ -112,61 +116,19 @@
     return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string());
 }
 
-static JNIEnv* AudioSystem_getJNIEnv(bool* needsDetach) {
-    *needsDetach = false;
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    if (env == NULL) {
-        JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
-        JavaVM* vm = AndroidRuntime::getJavaVM();
-        int result = vm->AttachCurrentThread(&env, (void*) &args);
-        if (result != JNI_OK) {
-            ALOGE("thread attach failed: %#x", result);
-            return NULL;
-        }
-        *needsDetach = true;
-    }
-    return env;
-}
-
-static void AudioSystem_detachJNI() {
-    JavaVM* vm = AndroidRuntime::getJavaVM();
-    int result = vm->DetachCurrentThread();
-    if (result != JNI_OK) {
-        ALOGE("thread detach failed: %#x", result);
-    }
-}
-
 static void
 android_media_AudioSystem_error_callback(status_t err)
 {
-    bool needsDetach = false;
-    JNIEnv *env = AudioSystem_getJNIEnv(&needsDetach);
-
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
     if (env == NULL) {
         return;
     }
 
     jclass clazz = env->FindClass(kClassPathName);
 
-    int error;
-
-    switch (err) {
-    case DEAD_OBJECT:
-        error = kAudioStatusMediaServerDied;
-        break;
-    case NO_ERROR:
-        error = kAudioStatusOk;
-        break;
-    default:
-        error = kAudioStatusError;
-        break;
-    }
-
-    env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error);
-
-    if (needsDetach) {
-        AudioSystem_detachJNI();
-    }
+    env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,
+                              "errorCallbackFromNative","(I)V"),
+                              check_AudioSystem_Command(err));
 }
 
 static int
@@ -313,6 +275,12 @@
     return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice);
 }
 
+static int
+android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz)
+{
+    return check_AudioSystem_Command(AudioSystem::checkAudioFlinger());
+}
+
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
@@ -340,6 +308,7 @@
     {"getPrimaryOutputFrameCount",   "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
     {"getOutputLatency",    "(I)I",     (void *)android_media_AudioSystem_getOutputLatency},
     {"setLowRamDevice",     "(Z)I",     (void *)android_media_AudioSystem_setLowRamDevice},
+    {"checkAudioFlinger",    "()I",     (void *)android_media_AudioSystem_checkAudioFlinger},
 };
 
 int register_android_media_AudioSystem(JNIEnv *env)
diff --git a/docs/html/tools/revisions/platforms.jd b/docs/html/tools/revisions/platforms.jd
index 820edbd..7cf3735 100644
--- a/docs/html/tools/revisions/platforms.jd
+++ b/docs/html/tools/revisions/platforms.jd
@@ -22,20 +22,31 @@
 
 
 
-<p>To develop an Android app, you must install at least one Android platform from the SDK Manager
-against which you can compile your app. Often, any given version of the Android will be revised
-with bug fixes or other changes, as denoted by the revision number. Below, you'll find the
-release notes for each version of the platform and the subsequent revisions to the platform
-version.</p>
+<p>This document provides information about Android platform releases. In order to compile your
+application against a particular platform release, you must download and install the SDK Platform
+for that release. If you want to test your application on an emulator, you must also download at
+least one system image for that platform release.</p>
 
-<p>To determine what revision of an Android platform you have installed, refer to the
-<strong>Installed Packages</strong> listing in the Android
+<p>Each platform release includes system images that support a specific processor architecture,
+such as ARM EABI, Intel x86 or MIPS. Platform releases also include a system image that contains
+Google APIs. The <a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> lists available
+platform system images under each platform version header, for example:</p>
+
+<ul>
+  <li>ARM EABI v7a System Image</li>
+  <li>Intel x86 Atom System Image</li>
+  <li>MIPS System Image</li>
+  <li>Google APIs</li>
+</ul>
+
+<p>To determine what revisions of an Android platform you have installed, refer to the
+<em>Packages</em> listing in the Android
 <a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a>.</p>
 
 <p class="caution"><strong>Important:</strong> To download the most recent Android
-system components from the Android SDK Manager, you must first update the SDK Tools to
-revision 22 or later and restart the SDK Manager. If you do not,
-the latest Android system components will not be available for download.</p>
+system components from the Android SDK Manager, you must first update the SDK Tools to the
+most recent release and restart the SDK Manager. If you do not, the latest Android system
+components will not be available for download.</p>
 
 
 
@@ -46,6 +57,25 @@
 
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png"
+class="toggle-content-img" alt="" />Revision 2</a> <em>(August 2013)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <p>Maintenance update. The system version is 4.3.</p>
+    <dl>
+      <dt>Dependencies:</dt>
+      <dd>Android SDK Platform-tools r18 or higher is required.</dd>
+      <dd>Android SDK Tools 22.0.4 or higher is recommended.</dd>
+    </dl>
+
+  </div>
+</div>
+
+<div class="toggle-content closed">
+
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png"
 class="toggle-content-img" alt="" />Revision 1</a> <em>(July 2013)</em>
   </p>
 
@@ -61,6 +91,39 @@
   </div>
 </div>
 
+<h3 id="">Google APIs System Image</h3>
+
+<div class="toggle-content opened">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-opened.png"
+class="toggle-content-img" alt="" />Revision 2</a> <em>(August 2013)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <p>Maintenance update. This release includes
+    <a href="{@docRoot}google/play-services/index.html">Google Play Services</a> version 3.2.25,
+    allowing you to test your application in an emulator using the latest Google Play Services.</p>
+
+  </div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png"
+class="toggle-content-img" alt="" />Revision 1</a> <em>(July 2013)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <p>Initial release. This release includes
+    <a href="{@docRoot}google/play-services/index.html">Google Play Services</a> version 3.1.58.</p>
+
+  </div>
+</div>
+
+
+
 
 <h2 id="4.2">Android 4.2</h2>
 
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ef02cfd..be83581 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1316,19 +1316,6 @@
     }
 
     /**
-     * @hide
-     * Signals whether remote submix audio rerouting is enabled.
-     */
-    public void setRemoteSubmixOn(boolean on, int address) {
-        IAudioService service = getService();
-        try {
-            service.setRemoteSubmixOn(on, address);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in setRemoteSubmixOn", e);
-        }
-    }
-
-    /**
      * Sets audio routing to the wired headset on or off.
      *
      * @param on set <var>true</var> to route audio to/from wired
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 470c571..3478007 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -140,24 +140,22 @@
     private static final int MSG_PERSIST_MASTER_VOLUME = 2;
     private static final int MSG_PERSIST_RINGER_MODE = 3;
     private static final int MSG_MEDIA_SERVER_DIED = 4;
-    private static final int MSG_MEDIA_SERVER_STARTED = 5;
-    private static final int MSG_PLAY_SOUND_EFFECT = 6;
-    private static final int MSG_BTA2DP_DOCK_TIMEOUT = 7;
-    private static final int MSG_LOAD_SOUND_EFFECTS = 8;
-    private static final int MSG_SET_FORCE_USE = 9;
-    private static final int MSG_BT_HEADSET_CNCT_FAILED = 10;
-    private static final int MSG_SET_ALL_VOLUMES = 11;
-    private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 12;
-    private static final int MSG_REPORT_NEW_ROUTES = 13;
-    private static final int MSG_SET_FORCE_BT_A2DP_USE = 14;
-    private static final int MSG_SET_RSX_CONNECTION_STATE = 15; // change remote submix connection
-    private static final int MSG_CHECK_MUSIC_ACTIVE = 16;
-    private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 17;
-    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 18;
-    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 19;
-    private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 20;
-    private static final int MSG_BROADCAST_BT_CONNECTION_STATE = 21;
-    private static final int MSG_UNLOAD_SOUND_EFFECTS = 22;
+    private static final int MSG_PLAY_SOUND_EFFECT = 5;
+    private static final int MSG_BTA2DP_DOCK_TIMEOUT = 6;
+    private static final int MSG_LOAD_SOUND_EFFECTS = 7;
+    private static final int MSG_SET_FORCE_USE = 8;
+    private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
+    private static final int MSG_SET_ALL_VOLUMES = 10;
+    private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 11;
+    private static final int MSG_REPORT_NEW_ROUTES = 12;
+    private static final int MSG_SET_FORCE_BT_A2DP_USE = 13;
+    private static final int MSG_CHECK_MUSIC_ACTIVE = 14;
+    private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 15;
+    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 16;
+    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 17;
+    private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 18;
+    private static final int MSG_BROADCAST_BT_CONNECTION_STATE = 19;
+    private static final int MSG_UNLOAD_SOUND_EFFECTS = 20;
     // start of messages handled under wakelock
     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
@@ -181,8 +179,6 @@
     // protects mRingerMode
     private final Object mSettingsLock = new Object();
 
-    private boolean mMediaServerOk;
-
     private SoundPool mSoundPool;
     private final Object mSoundEffectsLock = new Object();
     private static final int NUM_SOUNDPOOL_CHANNELS = 4;
@@ -287,23 +283,13 @@
         public void onError(int error) {
             switch (error) {
             case AudioSystem.AUDIO_STATUS_SERVER_DIED:
-                if (mMediaServerOk) {
-                    sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SENDMSG_NOOP, 0, 0,
-                            null, 1500);
-                    mMediaServerOk = false;
-                }
-                break;
-            case AudioSystem.AUDIO_STATUS_OK:
-                if (!mMediaServerOk) {
-                    sendMsg(mAudioHandler, MSG_MEDIA_SERVER_STARTED, SENDMSG_NOOP, 0, 0,
-                            null, 0);
-                    mMediaServerOk = true;
-                }
+                sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED,
+                        SENDMSG_NOOP, 0, 0, null, 0);
                 break;
             default:
                 break;
             }
-       }
+        }
     };
 
     /**
@@ -500,6 +486,8 @@
         mMediaFocusControl = new MediaFocusControl(mAudioHandler.getLooper(),
                 mContext, /*VolumeController*/ mVolumePanel, this);
 
+        AudioSystem.setErrorCallback(mAudioSystemCallback);
+
         boolean cameraSoundForced = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_camera_sound_forced);
         mCameraSoundForced = new Boolean(cameraSoundForced);
@@ -529,15 +517,12 @@
         createStreamStates();
 
         readAndSetLowRamDevice();
-        mMediaServerOk = true;
 
         // Call setRingerModeInt() to apply correct mute
         // state on streams affected by ringer mode.
         mRingerModeMutedStreams = 0;
         setRingerModeInt(getRingerMode(), false);
 
-        AudioSystem.setErrorCallback(mAudioSystemCallback);
-
         // Register for device connection intent broadcasts.
         IntentFilter intentFilter =
                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
@@ -2393,26 +2378,6 @@
         }
     };
 
-    /** see AudioManager.setRemoteSubmixOn(boolean on) */
-    public void setRemoteSubmixOn(boolean on, int address) {
-        sendMsg(mAudioHandler, MSG_SET_RSX_CONNECTION_STATE,
-                SENDMSG_REPLACE /* replace with QUEUE when multiple addresses are supported */,
-                on ? 1 : 0 /*arg1*/,
-                address /*arg2*/,
-                null/*obj*/, 0/*delay*/);
-    }
-
-    private void onSetRsxConnectionState(int available, int address) {
-        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_REMOTE_SUBMIX,
-                available == 1 ?
-                        AudioSystem.DEVICE_STATE_AVAILABLE : AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                String.valueOf(address) /*device_address*/);
-        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX,
-                available == 1 ?
-                        AudioSystem.DEVICE_STATE_AVAILABLE : AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                String.valueOf(address) /*device_address*/);
-    }
-
     private void onCheckMusicActive() {
         synchronized (mSafeMediaVolumeState) {
             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
@@ -3453,21 +3418,17 @@
                     break;
 
                 case MSG_MEDIA_SERVER_DIED:
-                    if (!mMediaServerOk) {
+                    if (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK) {
                         Log.e(TAG, "Media server died.");
-                        // Force creation of new IAudioFlinger interface so that we are notified
-                        // when new media_server process is back to life.
-                        AudioSystem.setErrorCallback(mAudioSystemCallback);
                         sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SENDMSG_NOOP, 0, 0,
                                 null, 500);
+                        break;
                     }
-                    break;
-
-                case MSG_MEDIA_SERVER_STARTED:
                     Log.e(TAG, "Media server started.");
+
                     // indicate to audio HAL that we start the reconfiguration phase after a media
                     // server crash
-                    // Note that MSG_MEDIA_SERVER_STARTED message is only received when the media server
+                    // Note that we only execute this when the media server
                     // process restarts after a crash, not the first time it is started.
                     AudioSystem.setParameters("restarting=true");
 
@@ -3600,10 +3561,6 @@
                     break;
                 }
 
-                case MSG_SET_RSX_CONNECTION_STATE:
-                    onSetRsxConnectionState(msg.arg1/*available*/, msg.arg2/*address*/);
-                    break;
-
                 case MSG_CHECK_MUSIC_ACTIVE:
                     onCheckMusicActive();
                     break;
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 4805da5..661b0fd 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -177,12 +177,10 @@
     {
         synchronized (AudioSystem.class) {
             mErrorCallback = cb;
+            if (cb != null) {
+                cb.onError(checkAudioFlinger());
+            }
         }
-        // Calling a method on AudioFlinger here makes sure that we bind to IAudioFlinger
-        // binder interface death. Not doing that would result in not being notified of
-        // media_server process death if no other method is called on AudioSystem that reaches
-        // to AudioFlinger.
-        isMicrophoneMuted();
     }
 
     private static void errorCallbackFromNative(int error)
@@ -404,5 +402,5 @@
     public static native int getOutputLatency(int stream);
 
     public static native int setLowRamDevice(boolean isLowRamDevice);
-
+    public static native int checkAudioFlinger();
 }
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 903927b..d8ce36a 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -114,8 +114,6 @@
 
     boolean isBluetoothA2dpOn();
 
-    oneway void setRemoteSubmixOn(boolean on, int address);
-
     int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb,
             IAudioFocusDispatcher fd, String clientId, String callingPackageName);
 
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 3e688db..1d2b889 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -179,6 +179,27 @@
          *  is applied.
          */
         public static final int VOICE_COMMUNICATION = 7;
+
+        /**
+         * Audio source for a submix of audio streams to be presented remotely.
+         * <p>
+         * An application can use this audio source to capture a mix of audio streams
+         * that should be transmitted to a remote receiver such as a Wifi display.
+         * While recording is active, these audio streams are redirected to the remote
+         * submix instead of being played on the device speaker or headset.
+         * </p><p>
+         * Certain streams are excluded from the remote submix, including
+         * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_ALARM},
+         * and {@link AudioManager#STREAM_NOTIFICATION}.  These streams will continue
+         * to be presented locally as usual.
+         * </p><p>
+         * Capturing the remote submix audio requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         */
+        public static final int REMOTE_SUBMIX = 8;
     }
 
     /**
@@ -294,7 +315,7 @@
      * @see android.media.MediaRecorder.AudioSource
      */
     public static final int getAudioSourceMax() {
-        return AudioSource.VOICE_COMMUNICATION;
+        return AudioSource.REMOTE_SUBMIX;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index fb2348e..34e3013 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -430,7 +430,8 @@
         @Override
         public void onServiceStateChanged(ServiceState state) {
             if (DEBUG) {
-                Log.d(TAG, "onServiceStateChanged state=" + state.getState());
+                Log.d(TAG, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
+                        + " dataState=" + state.getDataRegState());
             }
             mServiceState = state;
             updateTelephonySignalStrength();
@@ -506,10 +507,16 @@
 
     private boolean hasService() {
         if (mServiceState != null) {
-            switch (mServiceState.getState()) {
-                case ServiceState.STATE_OUT_OF_SERVICE:
+            // Consider the device to be in service if either voice or data service is available.
+            // Some SIM cards are marketed as data-only and do not support voice service, and on
+            // these SIM cards, we want to show signal bars for data service as well as the "no
+            // service" or "emergency calls only" text that indicates that voice is not available.
+            switch(mServiceState.getVoiceRegState()) {
                 case ServiceState.STATE_POWER_OFF:
                     return false;
+                case ServiceState.STATE_OUT_OF_SERVICE:
+                case ServiceState.STATE_EMERGENCY_ONLY:
+                    return mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
                 default:
                     return true;
             }
diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java
index f89917c3..846a74d 100644
--- a/services/java/com/android/server/display/WifiDisplayController.java
+++ b/services/java/com/android/server/display/WifiDisplayController.java
@@ -83,11 +83,6 @@
     private static final int CONNECT_MAX_RETRIES = 3;
     private static final int CONNECT_RETRY_DELAY_MILLIS = 500;
 
-    // A unique token to identify the remote submix that is managed by Wifi display.
-    // It must match what the media server uses when it starts recording the submix
-    // for transmission.  We use 0 although the actual value is currently ignored.
-    private static final int REMOTE_SUBMIX_ADDRESS = 0;
-
     private final Context mContext;
     private final Handler mHandler;
     private final Listener mListener;
@@ -95,8 +90,6 @@
     private final WifiP2pManager mWifiP2pManager;
     private final Channel mWifiP2pChannel;
 
-    private final AudioManager mAudioManager;
-
     private boolean mWifiP2pEnabled;
     private boolean mWfdEnabled;
     private boolean mWfdEnabling;
@@ -146,9 +139,6 @@
     // True if RTSP has connected.
     private boolean mRemoteDisplayConnected;
 
-    // True if the remote submix is enabled.
-    private boolean mRemoteSubmixOn;
-
     // The information we have most recently told WifiDisplayAdapter about.
     private WifiDisplay mAdvertisedDisplay;
     private Surface mAdvertisedDisplaySurface;
@@ -164,8 +154,6 @@
         mWifiP2pManager = (WifiP2pManager)context.getSystemService(Context.WIFI_P2P_SERVICE);
         mWifiP2pChannel = mWifiP2pManager.initialize(context, handler.getLooper(), null);
 
-        mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
-
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
         intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
@@ -211,7 +199,6 @@
         pw.println("mRemoteDisplay=" + mRemoteDisplay);
         pw.println("mRemoteDisplayInterface=" + mRemoteDisplayInterface);
         pw.println("mRemoteDisplayConnected=" + mRemoteDisplayConnected);
-        pw.println("mRemoteSubmixOn=" + mRemoteSubmixOn);
         pw.println("mAdvertisedDisplay=" + mAdvertisedDisplay);
         pw.println("mAdvertisedDisplaySurface=" + mAdvertisedDisplaySurface);
         pw.println("mAdvertisedDisplayWidth=" + mAdvertisedDisplayWidth);
@@ -482,7 +469,6 @@
             mHandler.removeCallbacks(mRtspTimeout);
 
             mWifiP2pManager.setMiracastMode(WifiP2pManager.MIRACAST_DISABLED);
-            setRemoteSubmixOn(false);
             unadvertiseDisplay();
 
             // continue to next step
@@ -626,7 +612,6 @@
                 return; // done
             }
 
-            setRemoteSubmixOn(true);
             mWifiP2pManager.setMiracastMode(WifiP2pManager.MIRACAST_SOURCE);
 
             final WifiP2pDevice oldDevice = mConnectedDevice;
@@ -677,13 +662,6 @@
         }
     }
 
-    private void setRemoteSubmixOn(boolean on) {
-        if (mRemoteSubmixOn != on) {
-            mRemoteSubmixOn = on;
-            mAudioManager.setRemoteSubmixOn(on, REMOTE_SUBMIX_ADDRESS);
-        }
-    }
-
     private void handleStateChanged(boolean enabled) {
         mWifiP2pEnabled = enabled;
         updateWfdEnableState();