AudioRecord: Allow to share capture history.

Add the possibility for privileged applications to
share part of their audio capture history with another app.

Bug: 183705547
Test: regression on capture use cases

Change-Id: I2b6547eee1dcd840e06090f42f40beafa3facb46
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 21651af..6549236 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -525,31 +525,8 @@
         return nullptr;
     }
 
-    // TODO b/182392769: use identity util
-    std::optional<std::string> opPackageNameStr = identity.packageName;
-    if (!identity.packageName.has_value()) {
-        // If no package name is provided by the client, use the first associated with the uid
-        if (!packages.isEmpty()) {
-            opPackageNameStr =
-                VALUE_OR_FATAL(legacy2aidl_String16_string(packages[0]));
-        }
-    } else {
-        // If the provided package name is invalid, we force app ops denial by clearing the package
-        // name passed to OpPlayAudioMonitor
-        String16 opPackageLegacy = VALUE_OR_FATAL(
-            aidl2legacy_string_view_String16(opPackageNameStr.value_or("")));
-        if (std::find_if(packages.begin(), packages.end(),
-                [&opPackageLegacy](const auto& package) {
-                return opPackageLegacy == package; }) == packages.end()) {
-            ALOGW("The package name(%s) provided does not correspond to the uid %d, "
-                  "force muting the track", opPackageNameStr.value().c_str(), uid);
-            // Set null package name so hasOpPlayAudio will always return false.
-            opPackageNameStr = std::optional<std::string>();
-        }
-    }
-    Identity adjIdentity = identity;
-    adjIdentity.packageName = opPackageNameStr;
-    return new OpPlayAudioMonitor(adjIdentity, attr.usage, id);
+    Identity checkedIdentity = AudioFlinger::checkIdentityPackage(identity);
+    return new OpPlayAudioMonitor(checkedIdentity, attr.usage, id);
 }
 
 AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor(
@@ -2243,24 +2220,12 @@
         return nullptr;
     }
 
-    if (!identity.packageName.has_value() || identity.packageName.value().size() == 0) {
-        Vector<String16> packages;
-        // no package name, happens with SL ES clients
-        // query package manager to find one
-        PermissionController permissionController;
-        permissionController.getPackagesForUid(identity.uid, packages);
-        if (packages.isEmpty()) {
-            return nullptr;
-        } else {
-            Identity adjIdentity = identity;
-            adjIdentity.packageName =
-                VALUE_OR_FATAL(legacy2aidl_String16_string(packages[0]));
-            ALOGV("using identity:%s", adjIdentity.toString().c_str());
-            return new OpRecordAudioMonitor(adjIdentity);
-        }
+    Identity checkedIdentity = AudioFlinger::checkIdentityPackage(identity);
+    if (!checkedIdentity.packageName.has_value()
+            || checkedIdentity.packageName.value().size() == 0) {
+        return nullptr;
     }
-
-    return new OpRecordAudioMonitor(identity);
+    return new OpRecordAudioMonitor(checkedIdentity);
 }
 
 AudioFlinger::RecordThread::OpRecordAudioMonitor::OpRecordAudioMonitor(
@@ -2386,6 +2351,12 @@
     return binderStatusFromStatusT(mRecordTrack->setPreferredMicrophoneFieldDimension(zoom));
 }
 
+binder::Status AudioFlinger::RecordHandle::shareAudioHistory(
+        const std::string& sharedAudioPackageName, int64_t sharedAudioStartMs) {
+    return binderStatusFromStatusT(
+            mRecordTrack->shareAudioHistory(sharedAudioPackageName, sharedAudioStartMs));
+}
+
 // ----------------------------------------------------------------------------
 #undef LOG_TAG
 #define LOG_TAG "AF::RecordTrack"
@@ -2406,7 +2377,8 @@
             const Identity& identity,
             audio_input_flags_t flags,
             track_type type,
-            audio_port_handle_t portId)
+            audio_port_handle_t portId,
+            int64_t startTimeMs)
     :   TrackBase(thread, client, attr, sampleRate, format,
                   channelMask, frameCount, buffer, bufferSize, sessionId,
                   creatorPid,
@@ -2423,7 +2395,8 @@
         mRecordBufferConverter(NULL),
         mFlags(flags),
         mSilenced(false),
-        mOpRecordAudioMonitor(OpRecordAudioMonitor::createIfNeeded(identity, attr))
+        mOpRecordAudioMonitor(OpRecordAudioMonitor::createIfNeeded(identity, attr)),
+        mStartTimeMs(startTimeMs)
 {
     if (mCblk == NULL) {
         return;
@@ -2533,6 +2506,9 @@
             Mutex::Autolock _l(thread->mLock);
             RecordThread *recordThread = (RecordThread *) thread.get();
             priorState = mState;
+            if (!mSharedAudioPackageName.empty()) {
+                recordThread->shareAudioHistory_l("");
+            }
             recordThread->destroyTrack_l(this); // move mState to STOPPED, terminate
         }
         // APM portid/client management done outside of lock.
@@ -2719,6 +2695,37 @@
     }
 }
 
+status_t AudioFlinger::RecordThread::RecordTrack::shareAudioHistory(
+        const std::string& sharedAudioPackageName, int64_t sharedAudioStartMs) {
+
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+    if (callingUid != mUid || callingPid != mCreatorPid) {
+        return PERMISSION_DENIED;
+    }
+
+    Identity identity{};
+    identity.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
+    identity.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingPid));
+    if (!captureHotwordAllowed(identity)) {
+        return PERMISSION_DENIED;
+    }
+
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        RecordThread *recordThread = (RecordThread *)thread.get();
+        status_t status = recordThread->shareAudioHistory(
+                sharedAudioPackageName, mSessionId, sharedAudioStartMs);
+        if (status == NO_ERROR) {
+            mSharedAudioPackageName = sharedAudioPackageName;
+        }
+        return status;
+    } else {
+        return BAD_VALUE;
+    }
+}
+
+
 // ----------------------------------------------------------------------------
 #undef LOG_TAG
 #define LOG_TAG "AF::PatchRecord"