Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ce56593 authored by Narayan Kamath's avatar Narayan Kamath Committed by Android (Google) Code Review
Browse files

Merge "Attribute SOURCE_HOTWORD to OP_RECORD_AUDIO_HOTWORD."

parents 71fe1304 bf85d8bc
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ static String16 resolveCallingPackage(PermissionController& permissionController
}

static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
        uid_t uid, bool start) {
        uid_t uid, bool start, bool isHotwordSource) {
    // Okay to not track in app ops as audio server or media server is us and if
    // device is rooted security model is considered compromised.
    // system_server loses its RECORD_AUDIO permission when a secondary
@@ -87,8 +87,11 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
    }

    AppOpsManager appOps;
    const int32_t op = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
    const int32_t opRecordAudio = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);

    if (start) {
        const int32_t op = isHotwordSource ?
                AppOpsManager::OP_RECORD_AUDIO_HOTWORD : opRecordAudio;
        if (int32_t mode = appOps.startOpNoThrow(
                        op, uid, resolvedOpPackageName, /*startIfModeDefault*/ false);
                mode != AppOpsManager::MODE_ALLOWED) {
@@ -97,10 +100,11 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
            return false;
        }
    } else {
        if (int32_t mode = appOps.checkOp(op, uid, resolvedOpPackageName);
        // Always use OP_RECORD_AUDIO for checks at creation time.
        if (int32_t mode = appOps.checkOp(opRecordAudio, uid, resolvedOpPackageName);
                mode != AppOpsManager::MODE_ALLOWED) {
            ALOGE("Request check for \"%s\" (uid %d) denied by app op: %d, mode: %d",
                    String8(resolvedOpPackageName).c_str(), uid, op, mode);
                    String8(resolvedOpPackageName).c_str(), uid, opRecordAudio, mode);
            return false;
        }
    }
@@ -109,14 +113,15 @@ static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
}

bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
    return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false);
    return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false,
            /*is_hotword_source*/ false);
}

bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid) {
     return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true);
bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, bool isHotwordSource) {
     return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true, isHotwordSource);
}

void finishRecording(const String16& opPackageName, uid_t uid) {
void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSource) {
    // Okay to not track in app ops as audio server is us and if
    // device is rooted security model is considered compromised.
    if (isAudioServerOrRootUid(uid)) return;
@@ -129,7 +134,8 @@ void finishRecording(const String16& opPackageName, uid_t uid) {
    }

    AppOpsManager appOps;
    const int32_t op = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
    const int32_t op = isHotwordSource ? AppOpsManager::OP_RECORD_AUDIO_HOTWORD
            : appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
    appOps.finishOp(op, uid, resolvedOpPackageName);
}

+3 −2
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    FuzzedDataProvider data_provider(data, size);
    uid_t uid = data_provider.ConsumeIntegral<uid_t>();
    pid_t pid = data_provider.ConsumeIntegral<pid_t>();
    bool isHotword = data_provider.ConsumeBool();

    // There is not state here, and order is not significant,
    // so we can simply call all of the target functions
@@ -54,8 +55,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    std::string packageNameStr = data_provider.ConsumeRandomLengthString(kMaxStringLen);
    android::String16 opPackageName(packageNameStr.c_str());
    android::recordingAllowed(opPackageName, pid, uid);
    android::startRecording(opPackageName, pid, uid);
    android::finishRecording(opPackageName, uid);
    android::startRecording(opPackageName, pid, uid, isHotword);
    android::finishRecording(opPackageName, uid, isHotword);
    android::captureAudioOutputAllowed(pid, uid);
    android::captureMediaOutputAllowed(pid, uid);
    android::captureHotwordAllowed(opPackageName, pid, uid);
+2 −2
Original line number Diff line number Diff line
@@ -79,8 +79,8 @@ static inline bool isAudioServerOrMediaServerUid(uid_t uid) {
}

bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid);
void finishRecording(const String16& opPackageName, uid_t uid);
bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, bool isHotwordSource);
void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSource);
bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
bool captureMediaOutputAllowed(pid_t pid, uid_t uid);
bool captureVoiceCommunicationOutputAllowed(pid_t pid, uid_t uid);
+6 −3
Original line number Diff line number Diff line
@@ -573,7 +573,8 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId)
    }

    // check calling permissions
    if (!(startRecording(client->opPackageName, client->pid, client->uid)
    if (!(startRecording(client->opPackageName, client->pid, client->uid,
            client->attributes.source == AUDIO_SOURCE_HOTWORD)
            || client->attributes.source == AUDIO_SOURCE_FM_TUNER)) {
        ALOGE("%s permission denied: recording not allowed for uid %d pid %d",
                __func__, client->uid, client->pid);
@@ -661,7 +662,8 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId)
        client->active = false;
        client->startTimeNs = 0;
        updateUidStates_l();
        finishRecording(client->opPackageName, client->uid);
        finishRecording(client->opPackageName, client->uid,
                        client->attributes.source == AUDIO_SOURCE_HOTWORD);
    }

    return status;
@@ -687,7 +689,8 @@ status_t AudioPolicyService::stopInput(audio_port_handle_t portId)
    updateUidStates_l();

    // finish the recording app op
    finishRecording(client->opPackageName, client->uid);
    finishRecording(client->opPackageName, client->uid,
                    client->attributes.source == AUDIO_SOURCE_HOTWORD);
    AutoCallerClear acc;
    return mAudioPolicyManager->stopInput(portId);
}