Make audio effects work

This makes the built-in audio effects work again.
3rd party effect panels can be made to work by disabling the built-in one
in Settings.
TODO: implement selection mechanism for third party effect panels.

Bug: 35316970
Test: manual
Change-Id: I6cd1cfba909bf74c31f37e9ecedcb28046f9109b
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 072b0ea..8c37dbb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -241,6 +241,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.location.LocationManager;
+import android.media.audiofx.AudioEffect;
 import android.metrics.LogMaker;
 import android.net.Proxy;
 import android.net.ProxyInfo;
@@ -18243,7 +18244,9 @@
                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
-                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
+                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
+                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
+                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
             // Broadcast is either protected, or it's a public action that
             // we've relaxed, so it's fine for system internals to send.
             return;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 8d0111b..5b3495f 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -43,6 +43,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -72,6 +73,7 @@
 import android.media.MediaPlayer;
 import android.media.SoundPool;
 import android.media.VolumePolicy;
+import android.media.audiofx.AudioEffect;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
 import android.media.PlayerBase;
@@ -723,6 +725,9 @@
             RotationHelper.init(mContext, mAudioHandler);
         }
 
+        intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
+        intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
+
         context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
 
         LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
@@ -5462,6 +5467,9 @@
                         state == BluetoothAdapter.STATE_TURNING_OFF) {
                     disconnectAllBluetoothProfiles();
                 }
+            } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
+                    action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
+                handleAudioEffectBroadcast(context, intent);
             }
         }
     } // end class AudioServiceBroadcastReceiver
@@ -5497,6 +5505,27 @@
         }
     } // end class AudioServiceUserRestrictionsListener
 
+    private void handleAudioEffectBroadcast(Context context, Intent intent) {
+        String target = intent.getPackage();
+        if (target != null) {
+            Log.w(TAG, "effect broadcast already targeted to " + target);
+            return;
+        }
+        intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
+        // TODO this should target a user-selected panel
+        List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers(
+                intent, 0 /* flags */);
+        if (ril != null && ril.size() != 0) {
+            ResolveInfo ri = ril.get(0);
+            if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) {
+                intent.setPackage(ri.activityInfo.packageName);
+                context.sendBroadcastAsUser(intent, UserHandle.ALL);
+                return;
+            }
+        }
+        Log.w(TAG, "couldn't find receiver package for effect intent");
+    }
+
     private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
         PackageManager pm = mContext.getPackageManager();
         // Find the home activity of the user. It should not be killed to avoid expensive restart,