Check for app manifest opt-out from playback capture

Query the package manager to check if the app has not opt-out of its
playback being captured.

Test: adb shell audiorecorder   --target /data/file1.raw &
      adb shell am start -a android.intent.action.VIEW -d file:///system/media/audio/ringtones/Lollipop.ogg -t audio/ogg
      adb dumpsys media.audio_policy # check playback is not recorded
      # change media player manifest to allowPlaybackCapture=true
      adb dumpsys media.audio_policy # check playback is recorded
      kill %1
      adb pull /data/file1.raw && sox -r 48000 -e signed -b 16 -c 2 file1.raw file.wav&& audacity file.wav
      # check silence then sound

Bug: 111453086
Change-Id: Id6fb7d0e10c02b0473bcbc0786e8360536996f48
Signed-off-by: Kevin Rocard <krocard@google.com>
diff --git a/media/utils/include/mediautils/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
index 98f54c2..94370ee 100644
--- a/media/utils/include/mediautils/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -14,13 +14,22 @@
  * limitations under the License.
  */
 
+#ifndef ANDROID_MEDIAUTILS_SERVICEUTILITIES_H
+#define ANDROID_MEDIAUTILS_SERVICEUTILITIES_H
+
 #include <unistd.h>
 
+#include <android/content/pm/IPackageManagerNative.h>
 #include <binder/IMemory.h>
 #include <binder/PermissionController.h>
 #include <cutils/multiuser.h>
 #include <private/android_filesystem_config.h>
 
+#include <map>
+#include <optional>
+#include <string>
+#include <vector>
+
 namespace android {
 
 // Audio permission utilities
@@ -72,4 +81,31 @@
 bool dumpAllowed();
 bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
 status_t checkIMemory(const sp<IMemory>& iMemory);
+
+class MediaPackageManager {
+public:
+    /** Query the PackageManager to check if all apps of an UID allow playback capture. */
+    bool allowPlaybackCapture(uid_t uid) {
+        auto result = doIsAllowed(uid);
+        if (!result) {
+            mPackageManagerErrors++;
+        }
+        return result.value_or(false);
+    }
+    void dump(int fd, int spaces = 0) const;
+private:
+    static constexpr const char* nativePackageManagerName = "package_native";
+    std::optional<bool> doIsAllowed(uid_t uid);
+    sp<content::pm::IPackageManagerNative> retreivePackageManager();
+    sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest
+    uint_t mPackageManagerErrors = 0;
+    struct Package {
+        std::string name;
+        bool playbackCaptureAllowed = false;
+    };
+    using Packages = std::vector<Package>;
+    std::map<uid_t, Packages> mDebugLog;
+};
 }
+
+#endif // ANDROID_MEDIAUTILS_SERVICEUTILITIES_H